[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\nmax_line_length = off\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".eslintignore",
    "content": "**/build/\n**/dist/\n**/coverage/\n**/node_modules/\njest.config.cts\nsponsorkit.config.mts\n\n# FIXME: Remove\nwebsite/\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"root\": true,\n  \"env\": {\n    \"node\": true\n  },\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaVersion\": \"latest\",\n    \"sourceType\": \"module\",\n    \"project\": [\n      \"./tsconfig.json\",\n      \"./benchmarks/tsconfig.json\",\n      \"./examples/tsconfig.json\",\n      \"./scripts/tsconfig.json\",\n      \"./tests/tsconfig.json\"\n    ]\n  },\n  \"settings\": {\n    \"import/parsers\": {\n      \"@typescript-eslint/parser\": [\".ts\"]\n    },\n    \"import/resolver\": {\n      \"typescript\": {\n        \"alwaysTryTypes\": true,\n        \"project\": [\n          \"./tsconfig.json\",\n          \"./benchmarks/tsconfig.json\",\n          \"./examples/tsconfig.json\",\n          \"./scripts/tsconfig.json\",\n          \"./tests/tsconfig.json\"\n        ]\n      }\n    }\n  },\n  \"reportUnusedDisableDirectives\": true,\n  \"plugins\": [\"import\", \"@typescript-eslint\", \"eslint-plugin-tsdoc\", \"jest\"],\n  \"extends\": [\n    \"airbnb-base\",\n    \"airbnb-typescript/base\",\n    \"eslint:recommended\",\n    \"plugin:@cspell/recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    // \"plugin:@typescript-eslint/recommended-type-checked\",\n    \"plugin:@typescript-eslint/stylistic\",\n    // \"plugin:@typescript-eslint/stylistic-type-checked\",\n    \"plugin:import/recommended\",\n    \"plugin:import/typescript\",\n    \"plugin:jest/recommended\",\n    \"prettier\"\n  ],\n  \"rules\": {\n    \"tsdoc/syntax\": \"warn\",\n    \"semi\": \"off\",\n    \"@typescript-eslint/semi\": \"error\",\n    \"no-restricted-syntax\": \"off\",\n    \"curly\": [\"error\", \"all\"],\n    \"nonblock-statement-body-position\": [\"error\", \"below\"],\n    \"sort-imports\": [\"error\", { \"ignoreDeclarationSort\": true }],\n    \"import/order\": [\n      \"error\",\n      {\n        \"alphabetize\": {\n          \"caseInsensitive\": true,\n          \"order\": \"asc\"\n        },\n        \"groups\": [\"builtin\", \"external\", \"internal\", [\"sibling\", \"parent\"], \"index\", \"unknown\"],\n        \"newlines-between\": \"never\",\n        \"pathGroups\": [\n          { \"pattern\": \"@/**\", \"group\": \"internal\", \"position\": \"before\" },\n          { \"pattern\": \"type-graphql\", \"group\": \"external\" }\n        ],\n        \"pathGroupsExcludedImportTypes\": [\"builtin\"]\n      }\n    ],\n    \"import/no-default-export\": \"error\",\n    \"import/prefer-default-export\": \"off\",\n    \"no-unused-vars\": \"off\",\n    \"no-duplicate-imports\": \"error\",\n    \"@typescript-eslint/no-unused-vars\": [\n      \"error\",\n      {\n        \"argsIgnorePattern\": \"^_\",\n        \"varsIgnorePattern\": \"^_\",\n        \"caughtErrorsIgnorePattern\": \"^_\"\n      }\n    ],\n    \"@typescript-eslint/array-type\": [\"error\", { \"default\": \"array-simple\" }],\n    \"@typescript-eslint/consistent-type-imports\": [\n      \"error\",\n      {\n        \"disallowTypeAnnotations\": false,\n        \"fixStyle\": \"inline-type-imports\",\n        \"prefer\": \"type-imports\"\n      }\n    ],\n    \"@typescript-eslint/consistent-type-exports\": \"error\",\n    \"@typescript-eslint/consistent-type-definitions\": [\"error\", \"interface\"],\n    \"@typescript-eslint/no-inferrable-types\": [\n      \"error\",\n      { \"ignoreParameters\": true, \"ignoreProperties\": true }\n    ],\n    // FIXME: Remove\n    \"@typescript-eslint/ban-types\": [\n      \"error\",\n      {\n        \"types\": {\n          \"Function\": false,\n          \"Object\": false,\n          \"{}\": false\n        },\n        \"extendDefaults\": true\n      }\n    ],\n    // FIXME: Remove\n    \"@typescript-eslint/no-explicit-any\": \"off\"\n  }\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "*                 text=auto eol=lf\n\n# Source code\n*.bash            text eol=lf\n*.bat             text eol=crlf\n*.cmd             text eol=crlf\n*.coffee          text\n*.css             text diff=css\n*.htm             text diff=html\n*.html            text diff=html\n*.inc             text\n*.ini             text\n*.js              text\n*.json            text\n*.jsx             text\n*.less            text\n*.ls              text\n*.map             text -diff\n*.od              text\n*.onlydata        text\n*.php             text diff=php\n*.pl              text\n*.ps1             text eol=crlf\n*.py              text diff=python\n*.rb              text diff=ruby\n*.sass            text\n*.scm             text\n*.scss            text diff=css\n*.sh              text eol=lf\n*.sql             text\n*.styl            text\n*.tag             text\n*.ts              text\n*.tsx             text\n*.xml             text\n*.xhtml           text diff=html\n\n# Docker\nDockerfile        text\n\n# Documentation\n*.ipynb           text\n*.markdown        text diff=markdown\n*.md              text diff=markdown\n*.mdwn            text diff=markdown\n*.mdown           text diff=markdown\n*.mkd             text diff=markdown\n*.mkdn            text diff=markdown\n*.mdtxt           text\n*.mdtext          text\n*.txt             text\nAUTHORS           text\nCHANGELOG         text\nCHANGES           text\nCONTRIBUTING      text\nCOPYING           text\ncopyright         text\n*COPYRIGHT*       text\nINSTALL           text\nlicense           text\nLICENSE           text\nNEWS              text\nreadme            text\n*README*          text\nTODO              text\n\n# Templates\n*.dot             text\n*.ejs             text\n*.erb             text\n*.haml            text\n*.handlebars      text\n*.hbs             text\n*.hbt             text\n*.jade            text\n*.latte           text\n*.mustache        text\n*.njk             text\n*.phtml           text\n*.svelte          text\n*.tmpl            text\n*.tpl             text\n*.twig            text\n*.vue             text\n\n# Configs\n*.cnf             text\n*.conf            text\n*.config          text\n.editorconfig     text\n.env              text\n.gitattributes    text\n.gitconfig        text\n.htaccess         text\n*.lock            text -diff\npackage.json      text eol=lf\npackage-lock.json text -diff\npnpm-lock.yaml    text eol=lf -diff\n.prettierrc       text\nyarn.lock         text -diff\n*.toml            text\n*.yaml            text\n*.yml             text\nbrowserslist      text\nMakefile          text\nmakefile          text\n\n# Heroku\nProcfile          text\n\n# Graphics\n*.ai              binary\n*.bmp             binary\n*.eps             binary\n*.gif             binary\n*.gifv            binary\n*.ico             binary\n*.jng             binary\n*.jp2             binary\n*.jpg             binary\n*.jpeg            binary\n*.jpx             binary\n*.jxr             binary\n*.pdf             binary\n*.png             binary\n*.psb             binary\n*.psd             binary\n*.svg             text\n*.svgz            binary\n*.tif             binary\n*.tiff            binary\n*.wbmp            binary\n*.webp            binary\n\n# Audio\n*.kar             binary\n*.m4a             binary\n*.mid             binary\n*.midi            binary\n*.mp3             binary\n*.ogg             binary\n*.ra              binary\n\n# Video\n*.3gpp            binary\n*.3gp             binary\n*.as              binary\n*.asf             binary\n*.asx             binary\n*.avi             binary\n*.fla             binary\n*.flv             binary\n*.m4v             binary\n*.mng             binary\n*.mov             binary\n*.mp4             binary\n*.mpeg            binary\n*.mpg             binary\n*.ogv             binary\n*.swc             binary\n*.swf             binary\n*.webm            binary\n\n# Archives\n*.7z              binary\n*.gz              binary\n*.jar             binary\n*.rar             binary\n*.tar             binary\n*.zip             binary\n\n# Fonts\n*.ttf             binary\n*.eot             binary\n*.otf             binary\n*.woff            binary\n*.woff2           binary\n\n# Executables\n*.exe             binary\n*.pyc             binary\n\n# RC files\n*.*rc             text\n\n# Ignore files\n*.*ignore         text\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "* @MichalLytek\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: typegraphql\nopen_collective: typegraphql\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Something works incorrectly or doesn't work at all\n---\n\n**Describe the Bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nA quick guide how to reproduce the bug.\nYou can paste here code snippets or even better, provide a link to the repository with minimal reproducible code example.\n\n**Expected Behavior**\nA clear and concise description of what you expected to happen.\n\n**Logs**\nIf applicable, add some console logs to help explain your problem.\nYou can paste the errors with stack trace that were printed when the error occurred.\n\n**Environment (please complete the following information):**\n\n- OS: [e.g. Windows]\n- Node (e.g. 10.5.0)\n- Package version [e.g. 0.12.2] (please check if the bug still exist in newest release)\n- TypeScript version (e.g. 2.8.2)\n\n**Additional Context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Question or help request\n    url: https://github.com/MichalLytek/type-graphql/discussions\n    about: Github Discussions is the place to ask a question or discuss with other community members\n  - name: Prisma 2 integration\n    url: https://github.com/MichalLytek/typegraphql-prisma\n    about: All problems or a questions about `typegraphql-prisma` package should be placed in the separate repository\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation-issue-or-request.md",
    "content": "---\nname: Documentation issue or request\nabout: There's something wrong in docs or something is missing\n---\n\n**Describe the issue**\nA clear and concise description of what is wrong or what feature is missing.\nYou may ask here for guides, e.g. \"How to run TypeGraphQL on AWS Lamda?\" if nobody helped you on Github Discussions or StackOverflow.\n\n**Are you able to make a PR that fix this?**\nIf you can, it would be great if you create a pull request that fixes the docs, fills the gap with new chapter or new code example.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: You want to suggest an idea for this project\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\nYou can also propose how the new API should looks like.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/configs/changelog.json",
    "content": "{\n  \"categories\": [\n    {\n      \"title\": \"## 🚀 Enhancements\",\n      \"labels\": [\"Enhancement 🆕\"]\n    },\n    {\n      \"title\": \"## 🐛 Fixes\",\n      \"labels\": [\"Bugfix 🐛 🔨\"]\n    },\n    {\n      \"title\": \"## 🧪 Tests\",\n      \"labels\": [\"Test 🧪\"]\n    },\n    {\n      \"title\": \"## 📦 Dependencies\",\n      \"labels\": [\"Dependencies 📦\"]\n    },\n    {\n      \"title\": \"## 📚 Documentation\",\n      \"labels\": [\"Documentation 📖\"]\n    },\n    {\n      \"title\": \"## 🏠 Internal\",\n      \"labels\": [\"Chore 🔨\", \"Internal 🏠\"]\n    }\n  ]\n}\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"npm\"\n    directory: \"/\"\n    versioning-strategy: increase\n    schedule:\n      interval: \"weekly\"\n    ignore:\n      - dependency-name: \"*\"\n        update-types: [\"version-update:semver-patch\"]\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/check.yml",
    "content": "name: check\n\non:\n  push:\n    branches:\n      - master\n    tags:\n      - v*\n  pull_request:\n    branches:\n      - master\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  version:\n    name: Ensure package version match\n    if: startsWith(github.ref_name, 'v')\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Check Git tag format\n        env:\n          TYPE_GRAPHQL_REF_NAME: ${{ github.ref_name }}\n        run: |\n          _tag=\"$TYPE_GRAPHQL_REF_NAME\"\n          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\n            printf '[ERROR]: Git tag (%s) wrong format\\n' \"$_tag\"\n            exit 1\n          fi\n\n      - name: Read package.json version\n        uses: sergeysova/jq-action@v2\n        id: version_package\n        with:\n          cmd: jq --raw-output .version package.json\n\n      - name: Read GitHub version\n        uses: pozetroninc/github-action-get-latest-release@master\n        id: version_v_github\n        with:\n          owner: MichalLytek\n          repo: type-graphql\n          excludes: prerelease, draft\n\n      - name: Remove leading v* from GitHub version\n        id: version_github\n        env:\n          TYPE_GRAPHQL_VERSION: ${{ steps.version_v_github.outputs.release }}\n        run: |\n          _version=\"$TYPE_GRAPHQL_VERSION\"\n          printf 'value=%s\\n' \"${_version#?}\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Read Git tag version\n        id: version_gittag\n        env:\n          TYPE_GRAPHQL_REF_NAME: ${{ github.ref_name }}\n        run: |\n          _version=\"$TYPE_GRAPHQL_REF_NAME\"\n          printf 'value=%s\\n' \"${_version#?}\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Compare package.json with Git tag\n        uses: madhead/semver-utils@latest\n        id: comparison_package_gittag\n        with:\n          version: ${{ steps.version_package.outputs.value }}\n          compare-to: ${{ steps.version_gittag.outputs.value }}\n          lenient: false\n\n      - name: Compare Git tag with GitHub\n        uses: madhead/semver-utils@latest\n        id: comparison_gittag_github\n        with:\n          version: ${{ steps.version_gittag.outputs.value }}\n          compare-to: ${{ steps.version_github.outputs.value }}\n          lenient: false\n\n      - name: Check package.json == Git tag\n        env:\n          TYPE_GRAPHQL_COMPARISON: ${{ steps.comparison_package_gittag.outputs.comparison-result }}\n          TYPE_GRAPHQL_VERSION_PACKAGE: ${{ steps.version_package.outputs.value }}\n          TYPE_GRAPHQL_VERSION_TAG: ${{ steps.version_gittag.outputs.value }}\n        run: |\n          if [ ! \"$TYPE_GRAPHQL_COMPARISON\" = \"=\" ]; then\n            printf '[ERROR]: package.json (%s) != Git tag (%s)\\n' \"$TYPE_GRAPHQL_VERSION_PACKAGE\" \"$TYPE_GRAPHQL_VERSION_TAG\"\n            exit 1\n          fi\n\n      - name: Check Git tag > GitHub\n        env:\n          TYPE_GRAPHQL_COMPARISON: ${{ steps.comparison_gittag_github.outputs.comparison-result }}\n          TYPE_GRAPHQL_VERSION_TAG: ${{ steps.version_gittag.outputs.value }}\n          TYPE_GRAPHQL_VERSION_GITHUB: ${{ steps.version_github.outputs.value }}\n        run: |\n          if [ ! \"$TYPE_GRAPHQL_COMPARISON\" = \">\" ]; then\n            printf '[ERROR]: Git tag (%s) !> GitHub (%s)\\n' \"$TYPE_GRAPHQL_VERSION_TAG\" \"$TYPE_GRAPHQL_VERSION_GITHUB\"\n            exit 1\n          fi\n\n  check:\n    name: Build & Lint & Test\n    needs: version\n    if: always() && (needs.version.result == 'success' || needs.version.result == 'skipped')\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: true\n      matrix:\n        node-version: [20.x, 22.x, 24.x, 25.x]\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Setup Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      - name: Install Dependencies\n        run: |\n          npm ci\n\n      - name: Build\n        run: |\n          npm run build\n          npm run build:benchmarks\n\n      - name: Check\n        run: |\n          npm run check\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Test\n        run: npm run test:ci\n        env:\n          CI: true\n\n      - name: Upload code coverage\n        uses: codecov/codecov-action@v4\n        if: matrix.node-version == '24.x'\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "name: codeql\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n  schedule:\n    - cron: \"0 0 * * 0\"\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n    strategy:\n      fail-fast: false\n      matrix:\n        language:\n          - javascript-typescript\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v3\n        with:\n          languages: ${{ matrix.language }}\n          queries: security-and-quality\n          config: |\n            paths-ignore:\n              - \"**/node_modules\"\n              - \"**/*.test.ts\"\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v3\n"
  },
  {
    "path": ".github/workflows/license.yml",
    "content": "name: license\n\non:\n  schedule:\n    - cron: \"0 0 1 1 *\"\n\nconcurrency:\n  group: ${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  license:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - uses: FantasticFiasco/action-update-license-year@v3\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: release\n\non:\n  workflow_run:\n    workflows:\n      - check\n    types:\n      - completed\n\npermissions:\n  id-token: write # Required for OIDC\n  contents: read\n\nconcurrency:\n  group: ${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  release:\n    name: Release package on NPM\n    runs-on: ubuntu-latest\n    if: github.event.workflow_run.conclusion == 'success' && github.ref_name == 'master' && startsWith(github.event.workflow_run.head_branch, 'v')\n    permissions:\n      contents: write\n      id-token: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.workflow_run.head_branch }}\n\n      - name: Determine if version is prerelease\n        id: prerelease\n        env:\n          TYPE_GRAPHQL_VERSION: ${{ github.event.workflow_run.head_branch }}\n        run: |\n          _prerelease=\n          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\n            _prerelease=false\n          else\n            _prerelease=true\n          fi\n\n          printf 'value=%s\\n' \"$_prerelease\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 24.x\n          registry-url: \"https://registry.npmjs.org\"\n\n      - name: Install latest npm\n        run: |\n          npm install -g npm@latest\n\n      - name: Install Dependencies\n        run: |\n          npm ci\n\n      - name: Prepare package\n        run: |\n          npm run prepublishOnly\n        env:\n          TYPE_GRAPHQL_REF: ${{ github.event.workflow_run.head_branch }}\n\n      - name: Build Changelog\n        id: changelog\n        uses: mikepenz/release-changelog-builder-action@v5\n        with:\n          configuration: \"./.github/configs/changelog.json\"\n          failOnError: true\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Release\n        uses: softprops/action-gh-release@v2\n        with:\n          tag_name: ${{ github.event.workflow_run.head_branch }}\n          body: ${{ steps.changelog.outputs.changelog }}\n          prerelease: ${{ steps.prerelease.outputs.value == 'true' }}\n\n      - name: Publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          TYPE_GRAPHQL_PRERELEASE: ${{ steps.prerelease.outputs.value }}\n        run: |\n          _tag=\n          if [ \"$TYPE_GRAPHQL_PRERELEASE\" = \"true\" ]; then\n            _tag=\"next\"\n          else\n            _tag=\"latest\"\n          fi\n\n          npm publish --ignore-scripts --tag \"$_tag\"\n"
  },
  {
    "path": ".github/workflows/sponsor.yml",
    "content": "name: sponsor\n\non:\n  schedule:\n    - cron: \"0 0 * * *\"\n\nconcurrency:\n  group: ${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  sponsor:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: \"24.x\"\n\n      - name: Install Dependencies\n        run: |\n          npm ci\n\n      - name: Regenerate sponsors images\n        run: npm run gen:sponsorkit\n        env:\n          SPONSORKIT_GITHUB_TOKEN: ${{ secrets.SPONSORKIT_GITHUB_TOKEN }}\n          # SPONSORKIT_OPENCOLLECTIVE_KEY: ${{ secrets.SPONSORKIT_GITHUB_TOKEN_OPENCOLLECTIVE_TOKEN }}\n\n      - name: Commit updated images\n        uses: EndBug/add-and-commit@v9\n        with:\n          add: \"img/github-sponsors.svg website/static/img/github-sponsors.svg\"\n          message: \"chore(sponsors): update sponsors image\"\n          push: true\n          committer_name: github-actions[bot]\n          committer_email: github-actions[bot]@users.noreply.github.com\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/website.yml",
    "content": "name: website\n\non:\n  workflow_run:\n    workflows:\n      - check\n    types:\n      - completed\n\nconcurrency:\n  group: ${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  website:\n    name: Publish website\n    runs-on: ubuntu-latest\n    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'))\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.workflow_run.head_branch }}\n          fetch-depth: 0\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 24.x\n\n      - name: Install Dependencies\n        run: |\n          npm ci\n          npm ci --prefix ./website\n\n      - name: Build\n        run: |\n          npm run build --prefix ./website\n\n      - name: Publish\n        uses: peaceiris/actions-gh-pages@v4\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          publish_dir: ./website/build/type-graphql\n          user_name: \"github-actions[bot]\"\n          user_email: \"github-actions[bot]@users.noreply.github.com\"\n          full_commit_message: |\n            Deploy website based on ${{ github.event.workflow_run.head_sha }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Node.js modules\n**/node_modules/\n\n# Builded sources\n**/build/\n**/dist/\n\n# Coverage\n**/coverage/\n\n# IntelliJ stuffs\n.idea/\n\n# Parcel cache\n.cache\n.parcel-cache\n\n# Sponsorkit cache\n./images/.cache.json\n\n# Environments\n.env\n\n# Archives\n*.tar.gz\n*.tgz\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/usr/bin/env sh\n\n# shellcheck disable=SC1007 source=SCRIPTDIR/_/husky.sh\n. \"$(CDPATH= cd -- \"$(dirname -- \"$0\")\" && pwd)/_/husky.sh\"\n\nnpx --no -- lint-staged\n"
  },
  {
    "path": ".lintstagedrc",
    "content": "{\n  \"**/*.ts\": [\"eslint --fix\", \"prettier --write\"],\n  \"**/*.md\": [\"markdownlint --fix\", \"prettier --write\"],\n  \"!**/*.{ts,md}\": \"prettier --write --ignore-unknown\"\n}\n"
  },
  {
    "path": ".markdownlint.json",
    "content": "{\n  \"default\": true,\n  \"line-length\": false,\n  \"no-blanks-blockquote\": false\n}\n"
  },
  {
    "path": ".markdownlintignore",
    "content": "**/build/\n**/dist/\n**/coverage/\n**/node_modules/\nwebsite/blog/2018-03-25-medium-article.md\nwebsite/blog/2020-08-19-devto-article.md\nwebsite/versioned_docs/*\n# FIXME: Remove\nCHANGELOG.md\n"
  },
  {
    "path": ".npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": ".nvmrc",
    "content": "25\n"
  },
  {
    "path": ".prettierignore",
    "content": "**/build/\n**/dist/\n**/coverage/\n**/node_modules/\n/.husky/_/\n/.gitattributes\nwebsite/versioned_docs\nwebsite/versioned_sidebars\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"endOfLine\": \"lf\",\n  \"trailingComma\": \"all\",\n  \"tabWidth\": 2,\n  \"printWidth\": 100,\n  \"bracketSpacing\": true,\n  \"semi\": true,\n  \"singleQuote\": false,\n  \"arrowParens\": \"avoid\",\n  \"useTabs\": false\n}\n"
  },
  {
    "path": ".shellcheckrc",
    "content": "external-sources=true\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\n    \"bierner.comment-tagged-templates\",\n    \"DavidAnson.vscode-markdownlint\",\n    \"dbaeumer.vscode-eslint\",\n    \"EditorConfig.EditorConfig\",\n    \"esbenp.prettier-vscode\",\n    \"GitHub.vscode-github-actions\",\n    \"GraphQL.vscode-graphql\",\n    \"streetsidesoftware.code-spell-checker\",\n    \"timonwong.shellcheck\",\n    \"tlent.jest-snapshot-language-support\",\n    \"wayou.vscode-todo-highlight\"\n  ]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n  // Use IntelliSense to learn about possible attributes.\n  // Hover to view descriptions of existing attributes.\n  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Run example project\",\n      \"type\": \"node\",\n      \"request\": \"launch\",\n      \"cwd\": \"${workspaceFolder}/examples/${input:exampleProjectName}\",\n      \"args\": [\"./index.ts\"],\n      \"runtimeArgs\": [\"--nolazy\", \"-r\", \"ts-node/register/transpile-only\"],\n      \"skipFiles\": [\"<node_internals>/**\"]\n    }\n  ],\n  \"inputs\": [\n    {\n      \"id\": \"exampleProjectName\",\n      \"description\": \"Choose an example to run\",\n      \"type\": \"pickString\",\n      // TODO: add new examples here\n      \"options\": [\n        \"apollo-cache\",\n        \"apollo-federation\",\n        \"apollo-federation-2\",\n        \"authorization\",\n        \"automatic-validation\",\n        \"custom-validation\",\n        \"enums-and-unions\",\n        \"extensions\",\n        \"generic-types\",\n        \"graphql-scalars\",\n        \"interfaces-inheritance\",\n        \"middlewares-custom-decorators\",\n        \"mikro-orm\",\n        \"mixin-classes\",\n        \"query-complexity\",\n        \"redis-subscriptions\",\n        \"resolvers-inheritance\",\n        \"simple-subscriptions\",\n        \"simple-usage\",\n        \"tsyringe\",\n        \"typegoose\",\n        \"typeorm-basic-usage\",\n        \"typeorm-lazy-relations\",\n        \"using-container\",\n        \"using-scoped-container\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"typescript.tsdk\": \"${workspaceFolder}/node_modules/typescript/lib\",\n  \"editor.formatOnSave\": true,\n  \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"[jsonc]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\"\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog and release notes\n\n## Unreleased\n\n### Fixes\n\n- support resolver inheritance with dynamic field resolvers name by matching field resolvers by schemaName instead of methodName (#1806)\n\n<!-- Here goes all the unreleased changes descriptions -->\n\n## v2.0.0-rc.4\n\n### Fixes\n\n- prevent duplicated params when building schema multiple times (#1803)\n\n## v2.0.0-rc.3\n\n### Features\n\n- optimize performance of building metadata storage with HashMap caching for O(1) lookups (#1779)\n\n### Fixes\n\n- prevent enumerable undefined properties in input types instances (#1789)\n- add missing support for GraphQL extensions in interface types (#1776)\n\n### Others\n\n- **Breaking Change**: update `graphql-js` peer dependency to `^16.12.0`\n- **Breaking Change**: drop support for Node.js < 20.11.1\n- **Breaking Change**: update `graphql-scalars` peer dependency to `^1.25.0`\n- **Breaking Change**: update `class-validator` peer dependency to `>=0.14.3`\n\n## v2.0.0-rc.2\n\n### Features\n\n- support declaring middlewares on resolver class level (#620)\n- support declaring auth roles on resolver class level (#620)\n- make possible creating custom decorators on resolver class level - `createResolverClassMiddlewareDecorator`\n- support registering custom arg decorator via `createParameterDecorator` and its second argument `CustomParameterOptions` - `arg` (#1325)\n\n### Fixes\n\n- properly build multiple schemas with generic resolvers, args and field resolvers (#1321)\n\n### Others\n\n- **Breaking Change**: update `graphql-scalars` peer dependency to `^1.23.0`\n- **Breaking Change**: rename `createMethodDecorator` into `createMethodMiddlewareDecorator`\n- **Breaking Change**: rename `createParamDecorator` to `createParameterDecorator`\n\n## v2.0.0-rc.1\n\n### Features\n\n- support other `Reflect` polyfills than `reflect-metadata` by checking only used `Reflect` API (#1102)\n\n### Fixes\n\n- properly override fields of `@ArgsType` classes in deeply nested inheritance chain (#1644)\n- allow for leading spaces and multiline directives definitions in `@Directive` decorator (#1423)\n\n## v2.0.0-beta.6\n\n### Fixes\n\n- allow overriding field resolver method with different `name` arguments (#1284)\n- allow object type's `name` argument string contain a double underscore (`__`) when using `buildTypeDefsAndResolvers()` (#1309)\n\n### Others\n\n- **Breaking Change**: update `graphql-scalars` peer dependency to `^1.22.4`\n- properly configure esm build pipeline to publish working esm version of the package\n\n## v2.0.0-beta.4\n\n### Features\n\n- **Breaking Change**: expose shim as a package entry point `type-graphql/shim` (and `/node_modules/type-graphql/build/typings/shim.ts`)\n- **Breaking Change**: update `graphql-js` peer dependency to `^16.8.1`\n- **Breaking Change**: use `@graphql-yoga` instead of `graphql-subscriptions` as the subscriptions engine\n- **Breaking Change**: require providing `PubSub` implementation into `buildSchema` option when using `@Subscription`\n- **Breaking Change**: remove `@PubSub` in favor of directly importing created `PubSub` implementation\n- **Breaking Change**: remove `Publisher` and `PubSubEngine` types\n- **Breaking Change**: rename interface `ResolverFilterData` into `SubscriptionHandlerData` and `ResolverTopicData` into `SubscribeResolverData`\n- support defining directives on `@Field` of `@Args`\n- support defining directives on inline `@Arg`\n- allow passing custom validation function as `validateFn` option of `@Arg` and `@Args` decorators\n- add support for dynamic topic id function in `@Subscription` decorator option\n\n## v2.0.0-beta.3\n\n### Features\n\n- **Breaking Change**: update `graphql-js` peer dependency to `^16.7.1`\n- **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\n- **Breaking Change**: change `ClassType` constraint from `ClassType<T = any>` to `ClassType<T extends object = object>` in order to make it work properly with new TS features\n- **Breaking Change**: remove `dateScalarMode` option from `buildSchema`\n- **Breaking Change**: make `graphql-scalars` package a peer dependency and use date scalars from it instead of custom ones\n- **Breaking Change**: exported `GraphQLISODateTime` scalar has now a name `DateTimeISO`\n- **Breaking Change**: change `ValidatorFn` signature from `ValidatorFn<TArgs>` to `ValidatorFn<TContext>`\n- support custom validation function getting resolver data on validate\n- bring compatibility with the ESM ecosystem by exposing the double bundle of the `type-graphql` package (CJS and ESM versions)\n\n### Fixes\n\n- allow `ValidatorFn` to accept array of values (instead of only `object | undefined`)\n\n## v2.0.0-beta.2\n\n### Features\n\n- **Breaking Change**: `AuthChecker` type is now \"function or class\" - update to `AuthCheckerFn` if the function form is needed in the code\n- **Breaking Change**: update `graphql-js` peer dependency to `^16.6.0`\n- **Breaking Change**: `buildSchemaSync` is now also checking the generated schema for errors\n- **Breaking Change**: `validate` option of `buildSchema` is set to `false` by default - integration with `class-validator` has to be turned on explicitly\n- **Breaking Change**: `validate` option of `buildSchema` doesn't accept anymore a custom validation function - use `validateFn` option instead\n- support class-based auth checker, which allows for dependency injection\n- allow defining directives for interface types and theirs fields, with inheritance for object types fields (#744)\n- allow deprecating input fields and args (#794)\n- support disabling inferring default values (#793)\n- support readonly arrays for roles of `@Authorized` decorator (#935)\n- add sync version of `buildTypeDefsAndResolvers` function (#803)\n- lift restriction of listing all interfaces from inheritance chain in `implements` option of `@ObjectType` decorator (#1425)\n\n### Fixes\n\n- **Breaking Change**: properly emit types nullability when `defaultValue` is provided and remove `ConflictingDefaultWithNullableError` error (#751)\n- allow defining extension on field resolver level for fields also defined as a property of the class (#776)\n- fix throwing error when schema with dynamic default value was built again (#787)\n- fix converting inputs with fields of nested array type (#801)\n- disable broken exposing input types fields under a changed name via `@Field({ name: \"...\" })`\n- support overwriting fields of extended types (#1109)\n- properly execute args validation for nullable items array (#1328)\n\n### Others\n\n- **Breaking Change**: update `class-validator` peer dependency to `>=0.14.0`\n- **Breaking Change**: change build config to ES2021 - drop support for Node.js < 16.16.0\n- **Breaking Change**: remove support for loading resolvers by glob paths (`resolvers: string[]` build schema option)\n- **Breaking Change**: remove `isAbstract` legacy decorator option\n- **Breaking Change**: remove the `commentDescriptions` option from `PrintSchemaOptions` (no more support for `#` comments in SDL by GraphQL v16)\n\n## v1.1.1\n\n### Fixes\n\n- fix crashing when of union's or interface type's `resolveType` function returns `undefined` or `null` (#731)\n- fix crashing when no reflected type available for fields with params decorators (#724)\n- fix not registering object types implementing interface type when interface type is used as object type field type (#736)\n- properly transform nested array of input type classes (#737)\n\n## v1.1.0\n\n### Features\n\n- allow passing custom validation function as `validate` option to `buildSchema`\n- support defining deprecation reason and description of enum members (#714)\n\n### Fixes\n\n- **Breaking Change**: throw error when wrong type of value provided as arg or input for `GraphQLISODateTime` and `GraphQLTimestamp` scalars\n- don't include in schema the fields declared as `@FieldResolver` when that resolvers classes aren't provided in `resolvers` array\n- fix grammar in `CannotDetermineGraphQLTypeError` error message\n- properly inherit extensions from parent class and its fields\n\n## v1.0.0\n\n### Features\n\n- **Breaking Change**: emit in schema only types actually used by provided resolvers classes (#415)\n- **Breaking Change**: update `graphql-js` peer dependency to `^15.3.0`\n- **Breaking Change**: update `graphql-query-complexity` dependency to `^0.7.0` and drop support for `fieldConfigEstimator` (use `fieldExtensionsEstimator` instead)\n- **Breaking Change**: introduce `sortedSchema` option in `PrintSchemaOptions` and emit sorted schema file by default\n- **Breaking Change**: make `class-validator` a peer dependency of version `>=0.12.0` that needs to be installed manually (#366)\n- **Breaking Change**: remove `CannotDetermineTypeError` and make other error messages more detailed and specific\n- **Breaking Change**: remove legacy array inference - now explicit array syntax (`[Item]`) is required\n- update `TypeResolver` interface to match with `GraphQLTypeResolver` from `graphql-js`\n- add basic support for directives with `@Directive()` decorator (#369)\n- add possibility to tune up the performance and disable auth & middlewares stack for simple field resolvers (#479)\n- optimize resolvers execution paths to speed up a lot basic scenarios (#488)\n- add `@Extensions` decorator for putting metadata into GraphQL types config (#521)\n- add support for defining arguments and implementing resolvers for interface types fields (#579)\n- add `{ autoRegisterImplementations: false }` option to prevent automatic emitting in schema all the object types that implements used interface type (#595)\n- allow interfaces to implement other interfaces (#602)\n- expose `createResolversMap` utility that generates apollo-like resolvers object\n- support IoC containers which `.get()` method returns a `Promise` of resolver instance\n- update deps to newest major versions (`tslib`, `graphql-query-complexity`)\n\n### Fixes\n\n- **Breaking Change**: stop returning null for `GraphQLTimestamp` and `GraphQLISODateTime` scalars when returned value is not a `Date` instance - now it throws explicit error instead\n- **Breaking Change**: fix transforming and validating nested inputs and arrays (#462)\n- refactor union types function syntax handling to prevent possible errors with circular refs\n- remove duplicated entries for resolver classes that use inheritance (#499)\n- fix using `name` option on interface fields (#567)\n- fix not calling `authChecker` during subscribe phase for subscriptions (#578)\n- fix using shared union type in multiple schemas\n- fix using shared interface type in multiple schemas\n- fix calling field resolver without providing resolver class to `buildSchema`\n- fix generated TS union type for union type of object type classes extending themselves (#587)\n- fix using shared union and interface types in multiple schemas when `resolveType` is used\n- properly inherit directives while extending `@InputType` or `@ObjectType` classes (#626)\n- skip transforming empty array items into input classes\n\n### Others\n\n- **Breaking Change**: change build config to ES2018 - drop support for Node.js < 10.3\n- **Breaking Change**: remove deprecated `DepreciationOptions` interface\n- **Breaking Change**: remove deprecated direct array syntax for declaring union types\n\n## v0.17.6\n\n### Fixes\n\n- fix leaking resolver source code in `MissingSubscriptionTopicsError` error message (#489)\n\n## v0.17.5\n\n### Features\n\n- rename `DepreciationOptions` interface to `DeprecationOptions` and deprecate the old one\n- update deps to newest minor versions (`tslib`, `semver`, `graphql-query-complexity` and `glob`)\n- support nested array types (`@Field(type => [[Int]])`) (#393)\n- deprecate the direct array syntax for union types\n\n### Fixes\n\n- fix errors on circular refs in union types (#364) by adding the function syntax (`() => TClassTypes`)\n\n## v0.17.4\n\n### Features\n\n- add support for creating custom parameter decorators (#329)\n- allow to provide custom `subscribe` function in `@Subscription` decorator (#328)\n\n## v0.17.3\n\n### Features\n\n- update packages `semver` to `^6.0.0` and `graphql-subscriptions` to `^1.1.0`\n\n### Fixes\n\n- fix broken compatibility with newer `@types/graphql` due to using removed private types (e.g. `MaybePromise`) (#320)\n\n## v0.17.2\n\n### Features\n\n- add support for defining `resolveType` function for interfaces and unions (#319)\n- add support for setting default nullability for fields and return types (#297)\n- add `skipCheck` option in `buildSchema` to disable checking the correctness of a schema\n- add postinstall script for printing info on console about supporting the project\n\n### Fixes\n\n- fix generating plain resolvers for queries and mutations (compatibility with Apollo client state)\n\n## v0.17.1\n\n### Features\n\n- add support for emitting schema file in not existing directory (#269)\n- drop support for Node.js v6 (end of LTS in April 2019)\n\n### Fixes\n\n- fix typings discovery support for WebStorm (#276)\n- allow for returning plain objects when using `ObjectType`s that implements `InterfaceType`s or extends other classes (#160)\n\n## v0.17.0\n\n### Features\n\n- **Breaking Change**: make `graphql-js` packages a peer dependencies, bump `graphql` to `^14.1.1` and `@types/graphql` to `^14.0.7` (#239)\n- **Breaking Change**: remove `useContainer` function and allow to register container by `buildSchema` options (#241)\n- **Breaking Change**: change the default `PrintSchemaOptions` option `commentDescriptions` to false (no more `#` comments in SDL)\n- add support for passing `PrintSchemaOptions` in `buildSchema.emitSchemaFile` (e.g. `commentDescriptions: true` to restore previous behavior)\n- add `buildTypeDefsAndResolvers` utils function for generating apollo-like `typeDefs` and `resolvers` pair (#233)\n- add support for generic types (#255)\n\n### Fixes\n\n- **Breaking Change**: remove the `formatArgumentValidationError` helper as it's not compatible and not needed in new Apollo Server (#258)\n- fix calling return type getter function `@Field(type => Foo)` before finishing module evaluation (allow for extending circular classes using `require`)\n- fix nullifying other custom method decorators - call the method on target instance, not the stored reference to original function (#247)\n- fix throwing error when extending non args class in the `@ArgsType()` class\n- prevent unnecessary conversion of an object that is already an instance of the requested type (avoid constructor side-effects)\n\n## v0.16.0\n\n### Features\n\n- add support for default values in schema (#203)\n- add support for lists with nullable items (#211)\n\n### Fixes\n\n- fix browser shim (compatibility with polyfills for decorator support)\n\n## v0.15.0\n\n### Features\n\n- **Breaking Change**: upgrade `graphql` to `^14.0.2`, `graphql-subscriptions` to `^1.0.0` and `@types/graphql` to `^14.0.2`\n- update all other dependencies\n- drop support for Node.js v9\n- add capability to emit the schema definition file (\\*.gql) as a `buildSchema` option\n- add `emitSchemaDefinitionFile` helper function for emitting the schema SDL\n\n## v0.14.0\n\n### Features\n\n- **Breaking Change**: change `ClassType` type and export it in package index\n- **Breaking Change**: refactor generic `createUnionType` to remove the 10 types limit (note: requires TypeScript >=3.0.1)\n- add support for subscribing to dynamic topics - based on args/ctx/root (#137)\n- add support for query complexity analysis - integration with `graphql-query-complexity` (#139)\n\n## v0.13.1\n\n### Fixes\n\n- fix missing loosely typed overload signature for `createUnionType` (remove the 10 types limit)\n\n## v0.13.0\n\n### Features\n\n- make `class-validator` a virtual peer dependency and update it to newest `0.9.1` version\n- add support for creating scoped containers (#113)\n\n## v0.12.3\n\n### Features\n\n- add reflect-metadata checks and informative error if no polyfill provided\n- update `@types/graphql` to latest version (`^0.13.3`)\n\n### Fixes\n\n- fix throwing error when `of => objectType` wasn't provided in abstract resolver class\n- fix calling `Object.assign` with boolean arguments (#111)\n\n## v0.12.2\n\n### Features\n\n- add support for using type classes in browser (configure webpack to use decorators shim)\n\n### Fixes\n\n- fix swallowing false argument value (#101)\n\n## v0.12.1\n\n### Fixes\n\n- fix bug with overriding methods from parent resolver class (#95)\n\n## v0.12.0\n\n### Features\n\n- **Breaking Change**: remove deprecated `ActionData` and `FilterActionData` interfaces\n- add support for resolver classes inheritance\n- add `name` decorator option for `@Field` and `@FieldResolver` decorators that allows to set the schema name different than the property name\n\n## v0.11.3\n\n### Features\n\n- make auth checker feature generic typed (default `string` for backward compatibility)\n\n## v0.11.2\n\n### Features\n\n- attach `MetadataStorage` to global scope (support multiple packages/modules)\n- rename and deprecate `ActionData` and `FilterActionData` interfaces to `ResolverData` and `ResolverFilterData`\n\n## v0.11.1\n\n### Features\n\n- add support for returning null instead of throwing authorization error (`authMode` property of `buildSchema` config)\n- add support for generating object type field in schema from method with `@FieldResolver`\n\n### Fixes\n\n- fix bug when converting object scalars to target class instance (#65)\n\n## v0.11.0\n\n### Features\n\n- add support for creating and attaching middlewares, guards and interceptors to fields and resolvers\n- **Breaking Change**: remove deprecated decorators with `GraphQL` prefix and `{ array: true }` type option\n\n## v0.10.0\n\n### Features\n\n- add `buildSchemaSync` function to build the schema synchronously (unsafe! without additional errors checks)\n- update package dependencies\n- **Breaking Change**: update `@types/graphql` to `0.13.0`\n\n### Fixes\n\n- decorator option `validate` is now merged with `buildSchema`'s `validate` config instead of overwriting it\n\n## v0.9.1\n\n### Fixes\n\n- fix bug with extending non-TypeGraphQL classes\n\n## v0.9.0\n\n### Features\n\n- add support for GraphQL subscriptions using `graphql-subscriptions`\n- update package dependencies\n- deprecate `{ array: true }` type option\n\n## v0.8.1\n\n### Features\n\n- add `@Info()` decorator for injecting GraphQL resolve info to resolvers\n- add support for injecting parts of `root` and `context` objects with `@Root(\"field\")` and `@Ctx(\"field\")` decorators\n\n## v0.8.0\n\n### Features\n\n- add base support for GraphQL enums using TypeScript enums\n- add support for defining GraphQL unions\n- add support for importing resolvers from file path glob\n- deprecate decorators with `GraphQL` prefix - use `@ArgsType`, `@InputType`, `@InterfaceType`, `@ObjectType` and `@Resolver` instead\n\n### Fixes\n\n- fix not working array type notation in circular dependencies (correct thunk generation)\n\n## v0.7.0\n\n### Features\n\n- add authorization feature - `@Authorized` decorator and `authChecker` function in schema options ([see docs](https://github.com/MichalLytek/type-graphql/blob/master/docs/authorization.md))\n- add support for defining array type using mongoose-like notation `[Type]`\n- **Breaking Change**: remove deprecated `@GraphQLArgumentType` decorator - use `@GraphQLArgsType` instead\n\n## v0.6.0\n\n### Features\n\n- add support for defining GraphQL interfaces and implementing it by object types\n- add support for extending input, args, object and interface types classes\n- add support for implementing GraphQL interfaces without decorators duplication\n- **Breaking Change**: make `buildSchema` async - now it returns a Promise of `GraphQLSchema`\n- rename and deprecate `@GraphQLArgumentType` decorator - use `@GraphQLArgsType` instead\n\n### Fixes\n\n- allow for no args in `@GraphQLResolver` decorator to keep consistency with other resolver classes\n\n## v0.5.0\n\n### Features\n\n- create instance of root object when it's type provided in resolver\n- change `Date` scalar names to `GraphQLISODateTime` and `GraphQLTimestamp`\n- support only `Date` objects (instances) serialization in `GraphQLTimestamp` (and in `GraphQLISODateTime` too)\n- update package dependencies\n- add test suite with 92%+ coverage\n\n### Fixes\n\n- **Breaking change**: switch array `nullable` option behavior from `[Type]!` to `[Type!]`\n- add more detailed type reflection error message (parameters support)\n- fix `ResolverInterface` resolver function type (allow additional parameters)\n- add support for named param in `@GraphQLResolver` lambda and for object class as param\n\n## v0.4.0\n\n### Features\n\n- add basic support for automatic arguments and inputs validation using `class-validator`\n- add interface `ResolverInterface` for type checking of resolver class methods (field resolvers)\n- update `graphql` dependency from `^0.12.3` to `^0.13.0`\n\n### Fixes\n\n- fix default values for arg/input fields (class property initializers) - use `new` instead of `Object.create`\n\n## v0.3.0\n\n### Features\n\n- add support for descriptions in schema (types, args, queries, etc.)\n- add support for declaring deprecation reason on object fields and queries/mutations\n\n### Fixes\n\n- fix scalars ID alias (GraphQLID not GraphQLString)\n\n## v0.2.0\n\n### Features\n\n- add support for Date type (built-in scalar)\n- add support for custom scalars (and mapping it to TS types)\n- change `@Context` decorator name to `@Ctx`\n\n## v0.1.2\n\n### Fixes\n\n- fix missing type args in schema when declared in field resolver\n- fix missing resolver function when defined as type field method\n- fix creating instances of root object when internal fields are Promises (switch from `plainToClass` to vanilla JS)\n- fix converting field and resolvers args errors while converting gql objects (weird `prototype` stuffs)\n\n## v0.1.1\n\n### Features\n\n- add support for omitting return type when use type options, in selected decorators (`@Field`, `@Arg`)\n\n### Fixes\n\n- fix class getter resolvers bug - missing fields from prototype (`plainToClass` bug)\n\n## v0.1.0\n\n### Initial release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "<!-- markdownlint-disable MD033 -->\n\n# Contributing to TypeGraphQL\n\nWe would love for you to contribute to TypeGraphQL and help make it even better than it is today!\nAs a contributor, here are the guidelines we would like you to follow:\n\n- [Question or Problem?](#question)\n- [Issues and Bugs](#issue)\n- [Feature Requests](#feature)\n- [Submission Guidelines](#submit)\n- [Coding Rules](#rules)\n- [Commit Message Guidelines](#commit)\n\n<h2 id=\"question\">Got a Question or Problem?</h2>\n\nDo not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.\n\nInstead, consider using [Stack Overflow](https://stackoverflow.com/questions/tagged/typegraphql) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `typegraphql` tag.\n\nYou can also ask community for help using the [Github Discussion platform][discussions].\n\n<h2 id=\"issue\">Found a Bug?</h2>\n\nIf you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].\nEven better, you can [submit a Pull Request](#submit-pr) with a failing test case that reproduces the issue.\n\n<h2 id=\"feature\">Missing a Feature?</h2>\n\nYou can _request_ a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.\n\nIf you would like to _implement_ a new feature, please consider the size of the change in order to determine the right steps to proceed:\n\n- For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.\n  This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.\n\n- **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).\n\n<h2 id=\"submit\">Submission Guidelines</h2>\n\n<h3 id=\"submit-issue\">Submitting an Issue</h3>\n\nBefore 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.\n\nYou 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.\n\n<h3 id=\"submit-pr\">Submitting a Pull Request (PR)</h3>\n\nBefore you submit your Pull Request (PR) consider the following guidelines:\n\n1. Search [GitHub](https://github.com/MichalLytek/type-graphql/pulls) for an open or closed PR that relates to your submission.\n   You don't want to duplicate existing efforts.\n\n2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.\n   Discussing the design upfront helps to ensure that we're ready to accept your work.\n\n3. Fork this repo.\n\n4. Make your changes in a new git branch:\n\n   ```shell\n   git checkout -b my-fix-branch master\n   ```\n\n5. Create your patch, **including appropriate test cases**.\n\n6. Follow our [Coding Rules](#rules).\n\n7. Run the full test suite, and ensure that all tests pass.\n\n8. Commit your changes using a descriptive commit message that follows our [commit message guidelines](#commit).\n   Adherence to these conventions is necessary because release notes are automatically generated from these messages.\n\n   ```shell\n   git commit -a\n   ```\n\n   Note: the optional commit `-a` command line option will automatically \"add\" and \"rm\" edited files.\n\n9. Push your branch to GitHub:\n\n   ```shell\n   git push origin my-fix-branch\n   ```\n\n10. In GitHub, send a pull request to `type-graphql:master`.\n    Make sure to [allow edits from maintainers][allow-maintainer-edits].\n\nIf we ask for changes via code reviews then:\n\n- Make the required updates.\n- Re-run the test suites to ensure tests are still passing.\n- Rebase your branch and force push to your GitHub repository (this will update your Pull Request):\n\n  ```shell\n  git rebase master -i\n  git push -f\n  ```\n\nThat's it! Thank you for your contribution!\n\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable-next-line MD001 -->\n### After your pull request is merged\n<!-- prettier-ignore-end -->\n\nAfter your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:\n\n- Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:\n\n  ```shell\n  git push origin --delete my-fix-branch\n  ```\n\n- Check out the master branch:\n\n  ```shell\n  git checkout master -f\n  ```\n\n- Delete the local branch:\n\n  ```shell\n  git branch -D my-fix-branch\n  ```\n\n- Update your master with the latest upstream version:\n\n  ```shell\n  git pull --ff upstream master\n  ```\n\n<h2 id=\"rules\">Coding Rules</h2>\n\nTo ensure consistency throughout the source code, keep these rules in mind as you are working:\n\n- All features or bug fixes **must be covered by tests**.\n\n- The code must pass type checking and fullfil all the ESLint rules.\n\n<h2 id=\"commit\">Commit Message Guidelines</h2>\n\nFor more information checkout this [commit rules guide](https://www.conventionalcommits.org/en/v1.0.0).\n\n[github]: https://github.com/MichalLytek/type-graphql\n[discussions]: https://github.com/MichalLytek/type-graphql/discussions\n[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\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018-2026 Michał Lytek\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<!-- prettier-ignore-start -->\n<!-- markdownlint-disable-next-line MD041 -->\n![logo](./images/logo.png)\n<!-- prettier-ignore-end -->\n\n# TypeGraphQL\n\n[![release](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml)\n[![website](https://github.com/MichalLytek/type-graphql/actions/workflows/website.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/website.yml)\n[![codeql](https://github.com/MichalLytek/type-graphql/actions/workflows/codeql.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/codeql.yml)\n[![discord](https://img.shields.io/discord/1195751245386875040?logo=discord&color=%237289da)](https://discord.gg/cWnBAQcbg2)\n[![codecov](https://codecov.io/gh/MichalLytek/type-graphql/branch/master/graph/badge.svg)](https://codecov.io/gh/MichalLytek/type-graphql)\n[![npm](https://img.shields.io/npm/v/type-graphql?logo=npm&color=%23CC3534)](https://www.npmjs.com/package/type-graphql)\n[![open collective](https://opencollective.com/typegraphql/tiers/badge.svg)](https://opencollective.com/typegraphql)\n\nCreate [GraphQL](https://graphql.org) schema and resolvers with [TypeScript](https://www.typescriptlang.org), using classes and decorators!\n\n**<https://typegraphql.com>**\n\n[![donate](https://opencollective.com/typegraphql/donate/button.png?color=black)](https://opencollective.com/typegraphql)\n\n## Introduction\n\n**TypeGraphQL** makes developing GraphQL APIs an enjoyable process, i.e. by defining the schema using only classes and a bit of decorator magic.\n\nSo, to create types like object type or input type, we use a kind of DTO class.\nFor example, to declare `Recipe` type we simply create a class and annotate it with decorators:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nAnd we get the corresponding part of the schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nThen 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:\n\n```ts\n@Resolver(Recipe)\nclass RecipeResolver {\n  // dependency injection\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => [Recipe])\n  recipes() {\n    return this.recipeService.findAll();\n  }\n\n  @Mutation()\n  @Authorized(Roles.Admin) // auth guard\n  removeRecipe(@Arg(\"id\") id: string): boolean {\n    return this.recipeService.removeById(id);\n  }\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    return recipe.ratings.reduce((a, b) => a + b, 0) / recipe.ratings.length;\n  }\n}\n```\n\nAnd in this simple way, we get this part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes: [Recipe!]!\n}\n\ntype Mutation {\n  removeRecipe(id: String!): Boolean!\n}\n```\n\n## Motivation\n\nWe 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.\n\nFirst, 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.\n\nOnly then can we implement the resolvers using weird generic signatures and manually performing common tasks, like validation, authorization and loading dependencies:\n\n```ts\nexport const getRecipesResolver: GraphQLFieldResolver<void, Context, GetRecipesArgs> = async (\n  _,\n  args,\n  ctx,\n) => {\n  // common tasks repeatable for almost every resolver\n  const repository = TypeORM.getRepository(Recipe);\n  const auth = Container.get(AuthService);\n  await joi.validate(getRecipesSchema, args);\n  if (!auth.check(ctx.user)) {\n    throw new NotAuthorizedError();\n  }\n\n  // our business logic, e.g.:\n  return repository.find({ skip: args.offset, take: args.limit });\n};\n```\n\nThe biggest problem is 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 an entity class, the schema, as well as the interface. The same goes for inputs or arguments. It's easy to forget to update one piece or make a mistake with a single type. Also, what if we've made a typo in the field name? The rename feature (F2) won't work correctly.\n\nTools 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.\n\n**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.\n\n## Documentation\n\nThe documentation, installation guide, and detailed description of the API and all of its features are [available on the website](https://typegraphql.com).\n\n### Getting started\n\nA full getting started guide with a simple walkthrough (tutorial) can be found at [getting started docs](https://typegraphql.com/docs/getting-started.html).\n\n### Video tutorial\n\nIf you prefer video tutorials, you can watch [Ben Awad](https://github.com/benawad)'s [TypeGraphQL video series](https://www.youtube.com/playlist?list=PLN3n1USn4xlma1bBu3Tloe4NyYn9Ko8Gs) on YouTube.\n\n### Examples\n\nYou 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.\n\nThe [Tests folder](./tests) might also give you some tips on how to get various things done.\n\n## Security contact information\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure.\n\n## The future\n\nThe 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.\n\nHowever, 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).\n\nIf you have any interesting feature requests, feel free to open an issue on GitHub so we can discuss that!\n\n## Support\n\n**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.\n\nIt doesn't have a large company that sits behind it - its ongoing development is possible only thanks to the support of the community.\n\n[![donate](https://opencollective.com/typegraphql/donate/button.png?color=blue)](https://opencollective.com/typegraphql)\n\n### Gold Sponsors 🏆\n\n> 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.\n\n### Silver Sponsors 🥈\n\n<!-- markdownlint-disable MD033 -->\n\n| [<img src=\"./images/leofame.png\" width=\"250\" alt=\"Leofame\" />](https://leofame.com/buy-instagram-followers) |\n| :---------------------------------------------------------------------------------------------------------: |\n|                         [**Leofame**](https://leofame.com/buy-instagram-followers)                          |\n\n### Bronze Sponsors 🥉\n\n| [<img src=\"./images/live-graphics-system.png\" width=\"55\" alt=\"live graphic systems\" />](https://www.ligrsystems.com) | [<img src=\"./images/felix.png\" width=\"60\" alt=\"Felix Technologies\" />](https://github.com/joinlifex) | [<img src=\"./images/instinctools.svg\" width=\"100\" alt=\"instinctools\" />](https://instinctools.com/manufacturing) |\n| :------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------: |\n|                               [**Live Graphic Systems**](https://www.ligrsystems.com)                                |                       [**Felix Technologies**](https://github.com/joinlifex/)                        |                            [**instinctools**](https://instinctools.com/manufacturing)                            |\n\n| [<img src=\"./images/betwinner.svg\" width=\"100\" alt=\"BetWinner\" />](https://guidebook.betwinner.com/) | [<img src=\"./images/logo-buzzv.png\" width=\"70\" alt=\"BuzzVoice\" />](https://buzzvoice.com/) | [<img src=\"./images/socialwick-logo.png\" width=\"60\" alt=\"SocialWick\" />](https://www.socialwick.com/) | [<img src=\"./images/c19.png\" width=\"40\" alt=\"C19\" />](https://www.c19.cl/) | [<img src=\"./images/nove_casino.svg\" width=\"70\" alt=\"Nove Casino\" />](https://novecasino.net/) | [<img src=\"./images/play_fortune.png\" width=\"80\" alt=\"Play Fortune\" />](https://play-fortune.pl/gry-online/jednoreki-bandyta/) | [<img src=\"./images/moonkasyno.png\" width=\"60\" alt=\"MoonKasyno\" />](https://wechoosethemoon.org/kasyna-online/) | [<img src=\"./images/kasyno-online.png\" width=\"50\" alt=\"Kasyno Online\" />](https://www.casinobillions.com/pl/) | [<img src=\"./images/fbpostlikes.webp\" width=\"90\" alt=\"FBPostLikes\" />](https://www.fbpostlikes.com/) |\n| :--------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------: |\n|                          [**BetWinner**](https://guidebook.betwinner.com/)                           |                          [**BuzzVoice**](https://buzzvoice.com/)                           |                             [**SocialWick**](https://www.socialwick.com/)                             |                       [**C19**](https://www.c19.cl/)                       |                           [**Nove Casino**](https://novecasino.net/)                           |                           [**Play Fortune**](https://play-fortune.pl/gry-online/jednoreki-bandyta/)                            |                          [**MoonKasyno**](https://wechoosethemoon.org/kasyna-online/)                           |                            [**Kasyno Online**](https://www.casinobillions.com/pl/)                            |                           [**FBPostLikes**](https://www.fbpostlikes.com/)                            |\n\n| [<img src=\"./images/sidesmedia.png\" width=\"40\" alt=\"SidesMedia\" />](https://sidesmedia.com/) | [<img src=\"./images/social_followers.png\" width=\"60\" alt=\"Social Followers\" />](https://www.socialfollowers.uk/buy-tiktok-followers/) | [<img src=\"./images/ig-comment.png\" width=\"80\" alt=\"IG Comment\" />](https://igcomment.com/buy-instagram-comments/) | [<img src=\"./images/twicsy.svg\" width=\"100\" alt=\"Twicsy\" />](https://twicsy.com/buy-instagram-followers) | [<img src=\"./images/buzzoid.svg\" width=\"90\" alt=\"Buzzoid\" />](https://buzzoid.com/buy-instagram-followers/) | [<img src=\"./images/v4u.png\" width=\"80\" alt=\"Views4You\" />](https://views4you.com/) | [<img src=\"./images/payid_pookies.avif\" width=\"50\" alt=\"PayID Pokies\" />](https://au.trustpilot.com/review/bestpayidpokies.net) | [<img src=\"./images/fun88.png\" width=\"40\" alt=\"Fun88\" />](https://global.fun88.com/) |\n| :------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: |\n|                          [**SidesMedia**](https://sidesmedia.com/)                           |                             [**Social Followers**](https://www.socialfollowers.uk/buy-tiktok-followers/)                              |                          [**IG Comment**](https://igcomment.com/buy-instagram-comments/)                           |                         [**Twicsy**](https://twicsy.com/buy-instagram-followers)                         |                         [**Buzzoid**](https://buzzoid.com/buy-instagram-followers/)                         |                       [**Views4You**](https://views4you.com/)                       |                            [**PayID Pokies**](https://au.trustpilot.com/review/bestpayidpokies.net)                             |                        [**Fun88**](https://global.fun88.com/)                        |\n\n<!-- markdownlint-enable MD033 -->\n\n[![become a sponsor](https://opencollective.com/static/images/become_sponsor.svg)](https://opencollective.com/typegraphql)\n\n### Members 💪\n\n[![Members](https://opencollective.com/typegraphql/tiers/members.svg?avatarHeight=45&width=320&button=false)](https://opencollective.com/typegraphql#contributors)\n\n### GitHub Sponsors\n\n[![GitHub Sponsors](./images/github-sponsors.svg)](https://github.com/sponsors/TypeGraphQL)\n\n## Community\n\n- Visit the [Official Website](https://typegraphql.com)\n- Chat on [Discord](https://discord.gg/cWnBAQcbg2)\n\n## Want to help?\n\nWant to file a bug, contribute some code, or improve the documentation? Great! Please read our\nguidelines 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).\n"
  },
  {
    "path": "benchmarks/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"no-console\": \"off\",\n    \"max-classes-per-file\": \"off\",\n    \"class-methods-use-this\": \"off\",\n    \"import/no-extraneous-dependencies\": [\n      \"error\",\n      {\n        \"devDependencies\": true\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "benchmarks/array/graphql-js/async.ts",
    "content": "import {\n  GraphQLBoolean,\n  GraphQLInt,\n  GraphQLList,\n  GraphQLNonNull,\n  GraphQLObjectType,\n  GraphQLSchema,\n  GraphQLString,\n} from \"graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\nconst SampleObjectType: GraphQLObjectType = new GraphQLObjectType({\n  name: \"SampleObject\",\n  fields: () => ({\n    stringField: {\n      type: new GraphQLNonNull(GraphQLString),\n      resolve: async source => source.stringField,\n    },\n    numberField: {\n      type: new GraphQLNonNull(GraphQLInt),\n      resolve: async source => source.numberField,\n    },\n    booleanField: {\n      type: new GraphQLNonNull(GraphQLBoolean),\n      resolve: async source => source.booleanField,\n    },\n    nestedField: {\n      type: SampleObjectType,\n      resolve: async source => source.nestedField,\n    },\n  }),\n});\n\nconst schema = new GraphQLSchema({\n  query: new GraphQLObjectType({\n    name: \"Query\",\n    fields: {\n      multipleNestedObjects: {\n        type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(SampleObjectType))),\n        resolve: () =>\n          Array.from({ length: ARRAY_ITEMS }, (_, index) => ({\n            stringField: \"stringField\",\n            booleanField: true,\n            numberField: index,\n            nestedField: {\n              stringField: \"stringField\",\n              booleanField: true,\n              numberField: index,\n            },\n          })),\n      },\n    },\n  }),\n});\n\nrunBenchmark(schema).catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/graphql-js/standard.ts",
    "content": "import {\n  GraphQLBoolean,\n  GraphQLInt,\n  GraphQLList,\n  GraphQLNonNull,\n  GraphQLObjectType,\n  GraphQLSchema,\n  GraphQLString,\n} from \"graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\nconst SampleObjectType: GraphQLObjectType = new GraphQLObjectType({\n  name: \"SampleObject\",\n  fields: () => ({\n    stringField: {\n      type: new GraphQLNonNull(GraphQLString),\n    },\n    numberField: {\n      type: new GraphQLNonNull(GraphQLInt),\n    },\n    booleanField: {\n      type: new GraphQLNonNull(GraphQLBoolean),\n    },\n    nestedField: {\n      type: SampleObjectType,\n    },\n  }),\n});\n\nconst schema = new GraphQLSchema({\n  query: new GraphQLObjectType({\n    name: \"Query\",\n    fields: {\n      multipleNestedObjects: {\n        type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(SampleObjectType))),\n        resolve: () =>\n          Array.from({ length: ARRAY_ITEMS }, (_, index) => ({\n            stringField: \"stringField\",\n            booleanField: true,\n            numberField: index,\n            nestedField: {\n              stringField: \"stringField\",\n              booleanField: true,\n              numberField: index,\n            },\n          })),\n      },\n    },\n  }),\n});\n\nrunBenchmark(schema).catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/results.txt",
    "content": "Core i7 2700K @ 3.5GHz\nWindows 10 x64\n25 000 array items | 50 iterations\nNode.js v13.5\n\n-----\nTypeGraphQL\n\nstandard\n- 15.518s\n\nusing sync field resolvers\n- 18.180s\n\nusing async field resolvers\n- 39.934s\n\nusing getters\n- 31.207s\n\nstandard with global middleware\n- 62.664s\n\nwith `simpleResolvers: true`\n- 14.980s\n\n-----\n`graphql-js`\n\nstandard\n- 13.276s\n\nasync field resolvers\n- 25.630s\n"
  },
  {
    "path": "benchmarks/array/run.ts",
    "content": "import { type GraphQLSchema, execute } from \"graphql\";\nimport { gql } from \"graphql-tag\";\n\nconst BENCHMARK_ITERATIONS = 50;\nexport const ARRAY_ITEMS = 25000;\n\nexport async function runBenchmark(schema: GraphQLSchema) {\n  const multipleNestedObjectsQuery = gql`\n    query {\n      multipleNestedObjects {\n        stringField\n        booleanField\n        numberField\n        nestedField {\n          stringField\n          booleanField\n          numberField\n        }\n      }\n    }\n  `;\n  console.time(\"multipleNestedObjects\");\n  for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) {\n    // eslint-disable-next-line no-await-in-loop\n    const result = await execute({ schema, document: multipleNestedObjectsQuery });\n    console.assert(result.data !== undefined, \"result data is undefined\");\n    console.assert(\n      (result.data?.multipleNestedObjects as unknown[]).length === ARRAY_ITEMS,\n      \"result data is not a proper array\",\n    );\n    console.assert(\n      (result.data?.multipleNestedObjects as any[])[0].nestedField.booleanField === true,\n      \"data nestedField are incorrect\",\n    );\n  }\n  console.timeEnd(\"multipleNestedObjects\");\n}\n"
  },
  {
    "path": "benchmarks/array/type-graphql/async-field-resolvers.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  Field,\n  FieldResolver,\n  Int,\n  ObjectType,\n  Query,\n  Resolver,\n  Root,\n  buildSchema,\n} from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType()\nclass SampleObject {\n  @Field()\n  stringField!: string;\n\n  @Field(() => Int)\n  numberField!: number;\n\n  @Field()\n  booleanField!: boolean;\n\n  @Field({ nullable: true })\n  nestedField?: SampleObject;\n}\n\n@Resolver(SampleObject)\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject => ({\n        stringField: \"stringField\",\n        booleanField: true,\n        numberField: index,\n        nestedField: {\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n        },\n      }),\n    );\n  }\n\n  @FieldResolver()\n  async stringField(@Root() source: SampleObject) {\n    return source.stringField;\n  }\n\n  @FieldResolver()\n  async numberField(@Root() source: SampleObject) {\n    return source.numberField;\n  }\n\n  @FieldResolver()\n  async booleanField(@Root() source: SampleObject) {\n    return source.booleanField;\n  }\n\n  @FieldResolver()\n  async nestedField(@Root() source: SampleObject) {\n    return source.nestedField;\n  }\n}\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/type-graphql/simple-resolvers.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  Field,\n  Int,\n  type MiddlewareFn,\n  ObjectType,\n  Query,\n  Resolver,\n  buildSchema,\n} from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType({ simpleResolvers: true })\nclass SampleObject {\n  @Field()\n  stringField!: string;\n\n  @Field(() => Int)\n  numberField!: number;\n\n  @Field()\n  booleanField!: boolean;\n\n  @Field({ nullable: true })\n  nestedField?: SampleObject;\n}\n\n@Resolver()\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject => ({\n        stringField: \"stringField\",\n        booleanField: true,\n        numberField: index,\n        nestedField: {\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n        },\n      }),\n    );\n  }\n}\n\nconst log = (..._: unknown[]) => undefined; // noop\n\nconst loggingMiddleware: MiddlewareFn = ({ info }, next) => {\n  log(`${info.parentType.name}.${info.fieldName} accessed`);\n  return next();\n};\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n    globalMiddlewares: [loggingMiddleware],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/type-graphql/standard.ts",
    "content": "import \"reflect-metadata\";\nimport { Field, Int, ObjectType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType()\nclass SampleObject {\n  @Field()\n  stringField!: string;\n\n  @Field(() => Int)\n  numberField!: number;\n\n  @Field()\n  booleanField!: boolean;\n\n  @Field({ nullable: true })\n  nestedField?: SampleObject;\n}\n\n@Resolver()\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject => ({\n        stringField: \"stringField\",\n        booleanField: true,\n        numberField: index,\n        nestedField: {\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n        },\n      }),\n    );\n  }\n}\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/type-graphql/sync-field-resolvers.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  Field,\n  FieldResolver,\n  Int,\n  ObjectType,\n  Query,\n  Resolver,\n  Root,\n  buildSchema,\n} from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType()\nclass SampleObject {\n  @Field()\n  stringField!: string;\n\n  @Field(() => Int)\n  numberField!: number;\n\n  @Field()\n  booleanField!: boolean;\n\n  @Field({ nullable: true })\n  nestedField?: SampleObject;\n}\n\n@Resolver(SampleObject)\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject => ({\n        stringField: \"stringField\",\n        booleanField: true,\n        numberField: index,\n        nestedField: {\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n        },\n      }),\n    );\n  }\n\n  @FieldResolver()\n  stringField(@Root() source: SampleObject) {\n    return source.stringField;\n  }\n\n  @FieldResolver()\n  numberField(@Root() source: SampleObject) {\n    return source.numberField;\n  }\n\n  @FieldResolver()\n  booleanField(@Root() source: SampleObject) {\n    return source.booleanField;\n  }\n\n  @FieldResolver()\n  nestedField(@Root() source: SampleObject) {\n    return source.nestedField;\n  }\n}\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/type-graphql/sync-getters.ts",
    "content": "import \"reflect-metadata\";\nimport { Field, Int, ObjectType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType()\nclass SampleObject {\n  stringField!: string;\n\n  @Field({ name: \"stringField\" })\n  get getStringField(): string {\n    return this.stringField;\n  }\n\n  numberField!: number;\n\n  @Field(() => Int, { name: \"numberField\" })\n  get getNumberField(): number {\n    return this.numberField;\n  }\n\n  booleanField!: boolean;\n\n  @Field({ name: \"booleanField\" })\n  get getBooleanField(): boolean {\n    return this.booleanField;\n  }\n\n  nestedField?: SampleObject;\n\n  @Field(() => SampleObject, { name: \"nestedField\", nullable: true })\n  get getNestedField(): SampleObject | undefined {\n    return this.nestedField;\n  }\n}\n\n@Resolver(SampleObject)\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject =>\n        ({\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n          nestedField: {\n            stringField: \"stringField\",\n            booleanField: true,\n            numberField: index,\n          } as SampleObject,\n        }) as SampleObject,\n    );\n  }\n}\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/array/type-graphql/with-global-middleware.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  Field,\n  Int,\n  type MiddlewareFn,\n  ObjectType,\n  Query,\n  Resolver,\n  buildSchema,\n} from \"type-graphql\";\nimport { ARRAY_ITEMS, runBenchmark } from \"../run\";\n\n@ObjectType()\nclass SampleObject {\n  @Field()\n  stringField!: string;\n\n  @Field(() => Int)\n  numberField!: number;\n\n  @Field()\n  booleanField!: boolean;\n\n  @Field({ nullable: true })\n  nestedField?: SampleObject;\n}\n\n@Resolver()\nclass SampleResolver {\n  @Query(() => [SampleObject])\n  multipleNestedObjects(): SampleObject[] {\n    return Array.from(\n      { length: ARRAY_ITEMS },\n      (_, index): SampleObject => ({\n        stringField: \"stringField\",\n        booleanField: true,\n        numberField: index,\n        nestedField: {\n          stringField: \"stringField\",\n          booleanField: true,\n          numberField: index,\n        },\n      }),\n    );\n  }\n}\n\nconst log = (..._: unknown[]) => undefined; // noop\n\nconst loggingMiddleware: MiddlewareFn = ({ info }, next) => {\n  log(`${info.parentType.name}.${info.fieldName} accessed`);\n  return next();\n};\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n    globalMiddlewares: [loggingMiddleware],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/simple/graphql-js.ts",
    "content": "import { GraphQLObjectType, GraphQLSchema, GraphQLString } from \"graphql\";\nimport { runBenchmark } from \"./run\";\n\nconst SampleObject: GraphQLObjectType = new GraphQLObjectType({\n  name: \"SampleObject\",\n  fields: () => ({\n    sampleField: {\n      type: GraphQLString,\n    },\n    nestedField: {\n      type: SampleObject,\n    },\n  }),\n});\n\nconst schema = new GraphQLSchema({\n  query: new GraphQLObjectType({\n    name: \"Query\",\n    fields: {\n      singleObject: {\n        type: SampleObject,\n        resolve: () => ({ sampleField: \"sampleField\" }),\n      },\n      nestedObject: {\n        type: SampleObject,\n        resolve: () => ({\n          sampleField: \"sampleField\",\n          nestedField: {\n            sampleField: \"sampleField\",\n            nestedField: {\n              sampleField: \"sampleField\",\n              nestedField: {\n                sampleField: \"sampleField\",\n                nestedField: {\n                  sampleField: \"sampleField\",\n                },\n              },\n            },\n          },\n        }),\n      },\n    },\n  }),\n});\n\nrunBenchmark(schema).catch(console.error);\n"
  },
  {
    "path": "benchmarks/simple/results.txt",
    "content": "Core i7 2700K @ 3.5GHz\nWindows 10 x64\n100 000 iterations\n\n-----\nNode.js v10.17\n\nES2016 build\n-  singleObject: 4831.113ms\n-  nestedObject: 17067.581ms\n\nES2018 build\n- singleObject: 2196.958ms\n- nestedObject: 7311.419ms\n\ngraphql-js\n- singleObject: 871.424ms\n- nestedObject: 2206.372ms\n\n-----\nNode.js v13.2\n\nES2018 build\n- singleObject: 1.622s\n- nestedObject: 4.557s\n\nwithout field resolvers (`graphql-js` implicit ones)\n- singleObject: 1.465s\n- nestedObject: 3.086s\n\ngraphql-js\n- singleObject: 1.003s\n- nestedObject: 2.422s\n"
  },
  {
    "path": "benchmarks/simple/run.ts",
    "content": "import { type ExecutionResult, type GraphQLSchema, execute } from \"graphql\";\nimport { gql } from \"graphql-tag\";\n\nconst BENCHMARK_ITERATIONS = 100000;\n\nexport async function runBenchmark(schema: GraphQLSchema) {\n  const singleObjectQuery = gql`\n    query {\n      singleObject {\n        sampleField\n      }\n    }\n  `;\n  console.time(\"singleObject\");\n  for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) {\n    // eslint-disable-next-line no-await-in-loop\n    const result: ExecutionResult<any> = await execute({ schema, document: singleObjectQuery });\n    console.assert(result.data !== undefined, \"result data is undefined\");\n    console.assert(result.data?.singleObject !== undefined, \"data singleObject is undefined\");\n  }\n  console.timeEnd(\"singleObject\");\n\n  const nestedObjectQuery = gql`\n    query {\n      nestedObject {\n        sampleField\n        nestedField {\n          sampleField\n          nestedField {\n            sampleField\n            nestedField {\n              sampleField\n              nestedField {\n                sampleField\n              }\n            }\n          }\n        }\n      }\n    }\n  `;\n  console.time(\"nestedObject\");\n  for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) {\n    // eslint-disable-next-line no-await-in-loop\n    const result: ExecutionResult<any> = await execute({ schema, document: nestedObjectQuery });\n    console.assert(result.data !== undefined, \"result data is undefined\");\n    console.assert(\n      result.data.nestedObject.nestedField.nestedField.nestedField.nestedField.sampleField !==\n        undefined,\n      \"data nestedField are incorrect\",\n    );\n  }\n  console.timeEnd(\"nestedObject\");\n}\n"
  },
  {
    "path": "benchmarks/simple/type-graphql.ts",
    "content": "import \"reflect-metadata\";\nimport { Field, ObjectType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { runBenchmark } from \"./run\";\n\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField!: string;\n\n  @Field()\n  nestedField?: SampleObject;\n}\n\n@Resolver()\nclass SampleResolver {\n  @Query()\n  singleObject(): SampleObject {\n    return { sampleField: \"sampleField\" };\n  }\n\n  @Query()\n  nestedObject(): SampleObject {\n    return {\n      sampleField: \"sampleField\",\n      nestedField: {\n        sampleField: \"sampleField\",\n        nestedField: {\n          sampleField: \"sampleField\",\n          nestedField: {\n            sampleField: \"sampleField\",\n            nestedField: {\n              sampleField: \"sampleField\",\n            },\n          },\n        },\n      },\n    };\n  }\n}\n\nasync function main() {\n  const schema = await buildSchema({\n    resolvers: [SampleResolver],\n  });\n\n  await runBenchmark(schema);\n}\n\nmain().catch(console.error);\n"
  },
  {
    "path": "benchmarks/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./build\"\n  },\n  \"include\": [\".\", \"../src\"]\n}\n"
  },
  {
    "path": "cspell.json",
    "content": "{\n  \"version\": \"0.2\",\n  \"language\": \"en\",\n  \"useGitignore\": true,\n  \"import\": [\n    \"@cspell/dict-node/cspell-ext.json\",\n    \"@cspell/dict-npm/cspell-ext.json\",\n    \"@cspell/dict-shell/cspell-ext.json\",\n    \"@cspell/dict-typescript/cspell-ext.json\"\n  ],\n  \"ignorePaths\": [\n    \"**/build/\",\n    \"**/dist/\",\n    \"**/coverage/\",\n    \"**/node_modules/\",\n    \"**/package.json\",\n    \"./images/**/*.svg\",\n    \"./images/**/*.avif\",\n    // FIXME: Remove\n    \"website/\",\n    \"examples\"\n  ],\n  \"words\": [\n    \"amet\",\n    \"argumented\",\n    \"asynciterable\",\n    \"authed\",\n    \"awad\",\n    \"betwinner\",\n    \"buzzoid\",\n    \"buzzv\",\n    \"casinodeps\",\n    \"cdpath\",\n    \"codecov\",\n    \"codegen\",\n    \"codeql\",\n    \"Famety\",\n    \"Fansoria\",\n    \"fbpostlikes\",\n    \"gamstop\",\n    \"graming\",\n    \"graphiql\",\n    \"graphqlgen\",\n    \"graphqlid\",\n    \"graphqlisodate\",\n    \"graphqlisodatetime\",\n    \"Insfollowpro\",\n    \"instanceof\",\n    \"instinctools\",\n    \"inversifyjs\",\n    \"isodate\",\n    \"joiful\",\n    \"Kasyno\",\n    \"kaszinomagyar\",\n    \"Leofame\",\n    \"lifex\",\n    \"lovd\",\n    \"lytek\",\n    \"michał\",\n    \"middlewares\",\n    \"mikroorm\",\n    \"moonkasyno\",\n    \"nestjs\",\n    \"netrc\",\n    \"nongamstopbets\",\n    \"Nove\",\n    \"opencollective\",\n    \"overfetching\",\n    \"paramtypes\",\n    \"payid\",\n    \"pookies\",\n    \"postbuild\",\n    \"realpath\",\n    \"returntype\",\n    \"shellcheck\",\n    \"sidesmedia\",\n    \"sindresorhus\",\n    \"Socialift\",\n    \"socialmention\",\n    \"socialwick\",\n    \"sponsorkit\",\n    \"supergraph\",\n    \"tiktok\",\n    \"todos\",\n    \"Tokmax\",\n    \"Twicsy\",\n    \"typedefs\",\n    \"typedi\",\n    \"typegql\",\n    \"typegraphql\",\n    \"typeof\",\n    \"typeorm\",\n    \"underfetching\",\n    \"webp\",\n    \"wordhint\",\n    \"Zahranicni\",\n    \"zahranicnicasino\"\n  ]\n}\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Documentation\n\n**The documentation has been prepared to be viewed on [TypeGraphQL website](https://typegraphql.com), please read it there.**\n"
  },
  {
    "path": "docs/authorization.md",
    "content": "---\ntitle: Authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## Declaration\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nHowever, declaring `@Authorized()` on all the resolver's class methods would be not only a tedious task but also an error-prone one, as it's easy to forget to put it on some newly added method, etc.\nHence, TypeGraphQL support declaring `@Authorized()` or the resolver class level. This way you can declare it once per resolver's class but you can still overwrite the defaults and narrows the authorization rules:\n\n```ts\n@Authorized()\n@Resolver()\nclass MyResolver {\n  // this will inherit the auth guard defined on the class level\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  // this one overwrites the resolver's one\n  // and registers roles required for this mutation\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\n## Runtime checks\n\nHaving all the metadata for authorization set, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization).\n"
  },
  {
    "path": "docs/aws-lambda.md",
    "content": "---\ntitle: AWS Lambda integration\n---\n\n## Using TypeGraphQL in AWS Lambda environment\n\nAWS Lambda environment is a bit different than a standard Node.js server deployment.\n\nHowever, 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.\n\nSo all we need to do is to assign the built schema to the local variable using the `??=` conditional assignment operator.\nWe can do the same thing for `ApolloServer`.\n\nBelow you you can find the full snippet for the AWS Lambda integration:\n\n```ts\nimport { APIGatewayProxyHandlerV2 } from \"aws-lambda\";\nimport { ApolloServer } from \"apollo-server-lambda\";\n\nlet cachedSchema: GraphQLSchema | null = null;\nlet cachedServer: ApolloServer | null = null;\n\nexport const handler: APIGatewayProxyHandlerV2 = async (event, context, callback) => {\n  // build TypeGraphQL executable schema only once, then read it from local \"cached\" variable\n  cachedSchema ??= await buildSchema({\n    resolvers: [RecipeResolver],\n  });\n\n  // create the GraphQL server only once\n  cachedServer ??= new ApolloServer({ schema: cachedSchema });\n\n  // make a handler for `aws-lambda`\n  return cachedServer.createHandler({})(event, context, callback);\n};\n```\n"
  },
  {
    "path": "docs/azure-functions.md",
    "content": "---\ntitle: Azure Functions Integration\n---\n\n## Using TypeGraphQL in Microsoft Azure Functions\n\nIntegrating TypeGraphQL with Azure Functions involves the following key steps:\n\n1. Generate GraphQL schema based on your resolvers\n2. Notify Apollo Server about your schema\n\nBelow is how you can implement the azure function entry point (with explanations in-line):\n\n```ts\n// index.ts\n\nimport \"reflect-metadata\";\nimport path from \"path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startServerAndCreateHandler } from \"@as-integrations/azure-functions\";\nimport { buildSchemaSync } from \"type-graphql\";\nimport { Container } from \"typedi\";\nimport { GraphQLFormattedError } from \"graphql\";\nimport { UserResolver } from \"YOUR_IMPORT_PATH\"; // TypeGraphQL Resolver\nimport { AccountResolver } from \"YOUR_IMPORT_PATH\"; // TypeGraphQL Resolver\n\n// Bundle resolvers to build the schema\nconst schema = buildSchemaSync({\n  // Include resolvers you'd like to expose to the API\n  // Deployment to Azure functions might fail if\n  // you include too much resolvers (means your app is too big)\n  resolvers: [\n    UserResolver,\n    AccountResolver,\n    // your other resolvers\n  ],\n\n  // Only build the GraphQL schema locally\n  // The resulting schema.graphql will be generated to the following path:\n  // Path: /YOUR_PROJECT/src/schema.graphql\n  emitSchemaFile: process.env.NODE_ENV === \"local\" ? path.resolve(\"./src/schema.graphql\") : false,\n  container: Container,\n  validate: true,\n});\n\n// Add schema into Apollo Server\nconst server = new ApolloServer({\n  // include your schema\n  schema,\n\n  // only allow introspection in non-prod environments\n  introspection: process.env.NODE_ENV !== \"production\",\n\n  // you can handle errors in your own styles\n  formatError: (err: GraphQLFormattedError) => err,\n});\n\n// Start the server(less handler/function)\nexport default startServerAndCreateHandler(server);\n```\n\nEach Azure Function needs to have an equivalent configuration file called `function.json`, here's how you can configure it:\n\n```json\n// function.json\n\n{\n  \"bindings\": [\n    {\n      \"authLevel\": \"anonymous\",\n      \"type\": \"httpTrigger\",\n      \"direction\": \"in\",\n      \"name\": \"req\",\n      \"route\": \"graphql\",\n      \"methods\": [\"get\", \"post\", \"options\"]\n    },\n    {\n      \"type\": \"http\",\n      \"direction\": \"out\",\n      \"name\": \"$return\"\n    }\n  ],\n  \"scriptFile\": \"../dist/handler-graphql/index.js\"\n}\n```\n\nFor better maintainability of your codebase, we recommend separate your Azure Functions into its own folders, away from the actual GraphQL Resolvers. Here's an example:\n\n```text\n/YOUR_PROJECT\n  /handlers\n    /handler-graphql\n      index.ts\n      function.json\n    /handler-SOME-OTHER-FUNCTION-1\n      index.ts\n      function.json\n    /handler-SOME-OTHER-FUNCTION-2\n      index.ts\n      function.json\n\n  /src\n    /resolvers\n      user.resolver.ts\n      account.resolver.ts\n    /services\n      user.service.ts\n      account.service.ts\n\n  package.json\n  host.json\n  .eslintrc.js\n  .prettierrc\n  .eslintignore\n  .prettierignore\n\netc etc etc...\n```\n"
  },
  {
    "path": "docs/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\n---\n\nAfter 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.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object we must provide a `resolvers` property, which is supposed to be an array of resolver classes:\n\n```ts\nimport { FirstResolver, SecondResolver } from \"./resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nBe aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema.\n\nSo 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`:\n\n```ts\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\nimport { FirstObject } from \"../app/src/types\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n  // Provide all the types that are missing in schema\n  orphanedTypes: [FirstObject],\n});\n```\n\nIn 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<T>` constraints:\n\n```ts\n// resolvers.ts\nexport const resolvers = [FirstResolver, SecondResolver] as const;\n\n// schema.ts\nimport { resolvers } from \"./resolvers\";\n\nconst schema = await buildSchema({ resolvers });\n```\n\nThere are also other options related to advanced features like [authorization](./authorization.md) or [validation](./validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [\n      // ... Resolvers classes\n    ],\n  });\n\n  // ...\n}\n\nbootstrap(); // Actually run the async function\n```\n\n## Create an HTTP GraphQL endpoint\n\nIn 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).\n\nBelow is an example using [`@apollo/server`](https://github.com/apollographql/apollo-server):\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install the `@apollo/server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt 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):\n\n```ts\nimport { makeExecutableSchema } from \"@graphql-tools/schema\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```ts\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ... Other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ... Rest of `ApolloClient` initialization code\n```\n\nThere's also a `sync` version of it - `buildTypeDefsAndResolversSync`:\n\n```ts\nconst { typeDefs, resolvers } = buildTypeDefsAndResolversSync({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "docs/browser-usage.md",
    "content": "---\ntitle: Browser usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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.\n\nThe steps to accomplish this are different, depending on the framework, bundler or compiler we use.\nHowever, 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.\n\n## CRA and similar\n\nWe simply add this plugin code to our webpack config:\n\n```js\nmodule.exports = {\n  // ... Rest of Webpack configuration\n  plugins: [\n    // ... Other existing plugins\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/shim\");\n    }),\n  ];\n}\n```\n\nIn 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.\n\n## Angular and similar\n\nIn 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:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"node_modules/type-graphql/build/typings/shim.ts\"]\n    }\n  }\n}\n```\n\n## Next.js and similar\n\nWhen 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.\n\nThe easiest way is to accomplish this is also done in `tsconfig.json` - add the same keys like in the example before to `compilerOptions`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"node_modules/type-graphql/build/typings/shim.ts\"]\n    }\n  }\n}\n```\n\nThen, `npm install -D tsconfig-paths` and enable it with `NODE_OPTIONS=\"-r tsconfig-paths/register\"` in our environment variables setup.\n"
  },
  {
    "path": "docs/complexity.md",
    "content": "---\ntitle: Query complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity).\n"
  },
  {
    "path": "docs/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\n---\n\nCustom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports three kinds of custom decorators - method, resolver class and parameter.\n\n## Method decorators\n\nUsing [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.\n\nThey work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodMiddlewareDecorator` helper function with our middleware logic and return its value:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Resolver class decorators\n\nSimilar to method decorators, we can create our own custom resolver class decorators.\nIn this case we need to call `createResolverClassMiddlewareDecorator` helper function, just like we did for `createMethodMiddlewareDecorator`:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createResolverClassMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe usage is then analogue - we just place it above the resolver class and pass the required arguments to it:\n\n```ts\n@ValidateArgs(MyArgsSchema) // Custom decorator\n@UseMiddleware(ResolveTime) // Explicit middleware\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\nThis way, we just need to put it once in the code and our custom decorator will be applied to all the resolver's queries or mutations. As simple as that!\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParameterDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParameterDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n### Custom `@Arg` decorator\n\nIn some cases we might want to create a custom decorator that will also register/expose an argument in the GraphQL schema.\nCalling both `Arg()` and `createParameterDecorator()` inside a custom decorator does not play well with the internals of TypeGraphQL.\n\nHence, the `createParameterDecorator()` function supports second argument, `CustomParameterOptions` which allows to set decorator metadata for `@Arg` under the `arg` key:\n\n```ts\nfunction RandomIdArg(argName = \"id\") {\n  return createParameterDecorator(\n    // here we do the logic of getting provided argument or generating a random one\n    ({ args }) => args[argName] ?? Math.round(Math.random() * MAX_ID_VALUE),\n    {\n      // here we provide the metadata to register the parameter as a GraphQL argument\n      arg: {\n        name: argName,\n        typeFunc: () => Int,\n        options: {\n          nullable: true,\n          description: \"Accepts provided id or generates a random one.\",\n        },\n      },\n    },\n  );\n}\n```\n\nThe usage of that custom decorator is very similar to the previous one and `@Arg` decorator itself:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    // custom decorator that will expose an arg in the schema\n    @RandomIdArg(\"id\") id: number,\n  ) {\n    return await this.recipesRepository.findById(id);\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "docs/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container).\n\nFor 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).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/master/examples/tsyringe).\n"
  },
  {
    "path": "docs/directives.md",
    "content": "---\ntitle: Directives\n---\n\n> 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.\n\nThough 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:\n\n```graphql\ntype Foo @auth(requires: USER) {\n  field: String!\n}\n\ntype Bar {\n  field: String! @auth(requires: USER)\n}\n```\n\nThat 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).\n\n**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator.\n\n## Usage\n\n### Declaring in schema\n\nBasically, we declare the usage of directives just like in SDL, with the `@` syntax:\n\n```ts\n@Directive('@deprecated(reason: \"Use newField\")')\n```\n\nCurrently, 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.\n\nSo 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:\n\n```ts\n@Directive(\"@auth(requires: USER)\")\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Directive(\"@auth(requires: USER)\")\n  @Field()\n  field: string;\n}\n\n@ArgsType()\nclass FooBarArgs {\n  @Directive('@deprecated(reason: \"Not used anymore\")')\n  @Field({ nullable: true })\n  baz?: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Directive(\"@auth(requires: ANY)\")\n  @Query()\n  foobar(@Args() { baz }: FooBarArgs): string {\n    return \"foobar\";\n  }\n\n  @Directive(\"@auth(requires: ADMIN)\")\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\nIn case of inline args using `@Arg` decorator, directives can be placed over the parameter of the class method:\n\n```ts\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Query()\n  foo(\n    @Directive('@deprecated(reason: \"Not used anymore\")')\n    @Arg(\"foobar\", { defaultValue: \"foobar\" })\n    foobar: string,\n  ) {\n    return \"foo\";\n  }\n\n  @FieldResolver()\n  bar(\n    @Directive('@deprecated(reason: \"Not used anymore\")')\n    @Arg(\"foobar\", { defaultValue: \"foobar\" })\n    foobar: string,\n  ) {\n    return \"bar\";\n  }\n}\n```\n\n> 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.\n\nAlso 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:\n\n```ts\n@ObjectType()\nclass Foo {\n  @Directive(\"@lowercase\")\n  @Directive('@deprecated(reason: \"Use `newField`\")')\n  @Directive(\"@hasRole(role: Manager)\")\n  @Field()\n  bar: string;\n}\n```\n\n### Providing the implementation\n\nBesides declaring the usage of directives, you also have to register the runtime part of the used directives.\n\n> 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`.\n\nIf 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:\n\n```ts\n// Build TypeGraphQL executable schema\nconst tempSchema = await buildSchema({\n  resolvers: [SampleResolver],\n  // Register the directives definitions\n  directives: [myDirective],\n});\n```\n\nThen you need to apply the schema transformer for your directive, that implements the desired logic of your directive:\n\n```ts\n// Transform and obtain the final schema\nconst schema = myDirectiveTransformer(tempSchema);\n```\n\nIf 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.\n\nHere is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools):\n\n```ts\nimport { mergeSchemas } from \"@graphql-tools/schema\";\nimport { renameDirective } from \"fake-rename-directive-package\";\n\n// Build TypeGraphQL executable schema\nconst schemaSimple = await buildSchema({\n  resolvers: [SampleResolver],\n});\n\n// Merge schema with sample directive type definitions\nconst schemaMerged = mergeSchemas({\n  schemas: [schemaSimple],\n  // Register the directives definitions\n  typeDefs: [renameDirective.typeDefs],\n});\n\n// Transform and obtain the final schema\nconst schema = renameDirective.transformer(schemaMerged);\n```\n"
  },
  {
    "path": "docs/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // Automatically create `schema.graphql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // Or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.graphql\"),\n  // Or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.graphql\",\n    sortedSchema: false, // By default the printed schema is sorted alphabetically\n  },\n});\n```\n\nThe 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.\n\n```ts\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.graphql\", schema);\n});\n```\n\n## Emit schema with custom directives\n\nCurrently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`.\n\nIf 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.\n\nBelow there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils):\n\n```ts\nimport { GraphQLSchema, lexicographicSortSchema } from \"graphql\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport fs from \"node:fs/promises\";\n\nexport async function emitSchemaDefinitionWithDirectivesFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n): Promise<void> {\n  const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema));\n  await fs.writeFile(schemaFilePath, schemaFileContent);\n}\n```\n\nThe usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`:\n\n```ts\nconst schema = await buildSchema(/*...*/);\n\nawait emitSchemaDefinitionWithDirectivesFile(\"/path/to/folder/schema.graphql\", schema);\n```\n"
  },
  {
    "path": "docs/enums.md",
    "content": "---\ntitle: Enums\n---\n\nNowadays 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.\n\nGraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema.\n\n## Creating enum\n\nLet'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:\n\n```ts\n// Implicit value 0, 1, 2, 3\nenum Direction {\n  UP,\n  DOWN,\n  LEFT,\n  RIGHT,\n}\n\n// Or explicit values\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n\nTo 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:\n\n```ts\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // Mandatory\n  description: \"The basic directions\", // Optional\n});\n```\n\nIn 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.:\n\n```ts\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n  SIDEWAYS = \"SIDEWAYS\",\n}\n\nregisterEnumType(Direction, {\n  name: \"Direction\",\n  description: \"The basic directions\",\n  valuesConfig: {\n    SIDEWAYS: {\n      deprecationReason: \"Replaced with Left or Right\",\n    },\n    RIGHT: {\n      description: \"The other left\",\n    },\n  },\n});\n```\n\nThis way, the additional info will be emitted in the GraphQL schema:\n\n```graphql\nenum Direction {\n  UP\n  DOWN\n  LEFT\n  \"\"\"\n  The other left\n  \"\"\"\n  RIGHT\n  SIDEWAYS @deprecated(reason: \"Replaced with Left or Right\")\n}\n```\n\n## Using enum\n\nThe 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:\n\n```ts\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // Mandatory\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, we can use our enum directly in our code 😉\n\n```ts\n@Resolver()\nclass SpriteResolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // Never reached\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n\n## Interoperability\n\nEnums 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`).\n\nSo 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.:\n\n```ts\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n"
  },
  {
    "path": "docs/esm.md",
    "content": "---\ntitle: ECMAScript Modules\n---\n\nSince `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules.\n\nThanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle.\n\n## TypeScript configuration\n\nIt's important to properly configure the project, so that it uses ESM correctly:\n\n- the `module` option should be set to `NodeNext`\n- the `moduleResolution` option should be set to `\"NodeNext\"`\n\nAll in all, the `tsconfig.json` file should looks like this:\n\n```json title=\"tsconfig.json\"\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n\n## Package.json configuration\n\nIt is also important to set `type` option to `\"module\"` in your `package.json` file:\n\n```json title=\"package.json\"\n{\n  \"type\": \"module\"\n}\n```\n\n## Imports\n\nApart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.:\n\n```ts\nimport { MyResolver } from \"./resolvers/MyResolver.js\";\n```\n"
  },
  {
    "path": "docs/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\n---\n\nOn 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.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/master/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/master/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/master/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/master/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/master/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/master/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "docs/extensions.md",
    "content": "---\ntitle: Extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see [more detailed examples of usage here](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions).\n"
  },
  {
    "path": "docs/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\n---\n\n## Resolvers\n\n### Should I implement a field resolver as an object type getter, a method or a resolver class method?\n\nThis depends on various factors:\n\n- if the resolver only needs access to the root/object value - use a getter\n- if the field has arguments\n  - and must perform side effects e.g. a database call - use a resolver class method and leverage the dependency injection mechanism\n  - otherwise, use object type methods (pure functions, calculations based on object values and arguments)\n- if the business logic must be separated from the type definition - use a resolver class method\n\n### Are there any global error handlers to catch errors from resolvers or services?\n\nUse middleware for this purpose - just wrap `await next()` in a try-catch block then register it as the first global middleware.\n\n### Why did I receive this error? `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`\n\nThis error occurs when the resolver (query, mutation, field) type is an interface/union and a plain object is returned from it.\nIn this case, what should be returned is an instance of the selected object type class in the resolver.\nOtherwise, `graphql-js` will not be able to correctly detect the underlying GraphQL type.\n\n## Bootstrapping\n\n### How do I fix this error? `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`\n\nThis error occurs mostly when there are more than one version of the `graphql-js` module in the project.\nIn 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`.\nWe can print the dependency tree by running `npm ls graphql` (or the yarn equivalent) to find the faulty dependencies.\nThen we should update or downgrade them until they all match the semver on `graphql`, e.g. `^14.0.0`.\nDependencies 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).\n\nThe 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'`.\nIn this case we repeat the same checks but for the `@types/graphql` module in our dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate a real `GraphQLInputType` type and should be used when we need a nested object in the args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When should I use the `() => [ItemType]` syntax?\n\nWe should use the `[ItemType]` syntax any time the field type or the return type is an array from a query or mutation.\n\nEven 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.\n\n### How can I define a tuple?\n\nUnfortunately, [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.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### Situations frequently arise where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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.\nHowever, 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:\n\n```ts\n@ObjectType() // Name inferred as 'Person' from class name\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "docs/generic-types.md",
    "content": "---\ntitle: Generic Types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "docs/getting-started.md",
    "content": "---\ntitle: Getting started\n---\n\n> Make sure you've completed all the steps described in the [installation instructions](./installation.md).\n\nTo explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundation of our API.\n\n## Types\n\nOur goal is to get the equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all its properties and types:\n\n```ts\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](./types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```ts\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements.\nThe detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](./resolvers.md).\n\n## Inputs and Arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```ts\n@InputType()\nclass NewRecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @ArrayMaxSize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` and `@ArrayMaxSize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ... Server\n```\n\nEt voilà! Now we have fully functional GraphQL schema!\nIf we print it, this is how it would look:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nA 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.\n\nFor more complicated cases, go to the [Examples section](./examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM.\n"
  },
  {
    "path": "docs/inheritance.md",
    "content": "---\ntitle: Inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance).\n"
  },
  {
    "path": "docs/installation.md",
    "content": "---\ntitle: Installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> **Prerequisites**\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, 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:\n\n```sh\nnpm install graphql graphql-scalars type-graphql\n```\n\nAlso, the `Reflect.metadata()` shim is required to make the type reflection work:\n\n```sh\nnpm install reflect-metadata\n# or\nnpm install core-js\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```ts\nimport \"reflect-metadata\";\n// or\nimport \"core-js/features/reflect\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`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:\n\n```js\n{\n  \"target\": \"es2021\" // Or newer if Node.js version supports it\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"commonjs\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "docs/interfaces.md",
    "content": "---\ntitle: Interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "docs/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic.\nExample object type:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL APIs quickly & easily!\n\n## Why?\n\nAs mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to take.\n\nFirst, 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.:\n\n```ts\nexport const getRecipesResolver: GraphQLFieldResolver<void, Context, GetRecipesArgs> = async (\n  _,\n  args,\n  ctx,\n) => {\n  // Common tasks repeatable for almost every resolver\n  const auth = Container.get(AuthService);\n  if (!auth.check(ctx.user)) {\n    throw new NotAuthorizedError();\n  }\n  await joi.validate(getRecipesSchema, args);\n  const repository = TypeORM.getRepository(Recipe);\n\n  // Business logic, e.g.:\n  return repository.find({ skip: args.offset, take: args.limit });\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "docs/middlewares.md",
    "content": "---\ntitle: Middleware and guards\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo attach middleware to a resolver method, place the `@UseMiddleware()` decorator above the method 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nIf we want to apply the middlewares to all the resolver's class methods, we can put the decorator on top of the class declaration:\n\n```ts\n@UseMiddleware(ResolveTime, LogAccess)\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(): number {\n    return Math.random();\n  }\n\n  @Query()\n  constantValue(): number {\n    return 21.37;\n  }\n}\n```\n\n> Be aware that resolver's class middlewares are executed first, before the method's ones.\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middlewares like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field, method or resolver class.\n\nHence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and a field. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "docs/migration-guide.md",
    "content": "---\ntitle: Migration Guide\nsidebar_label: v1.x -> v2.0\n---\n\n> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release.\n>\n> 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.\n\n## New `DateTimeISO` scalar name in schema\n\nOne 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.\n\nThis 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.\n\nFirst, you need to create an alias for the `GraphQLDateTimeISO` scalar:\n\n```ts\nimport { GraphQLDateTimeISO } from \"graphql-scalars\";\nimport { GraphQLScalarType } from \"graphql\";\n\nconst AliasedGraphQLDateTimeISO = new GraphQLScalarType({\n  ...GraphQLDateTimeISO.toConfig(),\n  name: \"DateTime\", // use old name\n});\n```\n\nAnd then register the scalars mapping in the schema you build, in order to overwrite the default date scalar:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: Date, scalar: AliasedGraphQLDateTimeISO }],\n});\n```\n\nAn 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.\n\n## Subscriptions\n\nThe new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature.\n\nIn previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system.\nHowever, it's become unmaintained in the last years and some alternatives has been developed in the meantime.\n\nSo 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.\n\nWe 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.\n\n### The `pubSub` option of `buildSchema`\n\nIt is now required to pass the `PubSub` instance as the config option of `buildSchema` function.\nPreviously, you could omit it and rely on the default one created by TypeGraphQL.\n\nThe 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.\n\nSimple example of the new API:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nBe aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\n### No `@PubSub` decorator\n\nThe consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance.\n\nHence, 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.\n\n### Renamed and removed types\n\nThere was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release.\n\nIf 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.\n\n- `ResolverFilterData` -> `SubscriptionHandlerData`\n- `ResolverTopicData` -> `SubscribeResolverData`\n\nAlso, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package.\n\n### Topic with Dynamic ID\n\nAs 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.\n\nYou can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id).\n"
  },
  {
    "path": "docs/nestjs.md",
    "content": "---\ntitle: NestJS Integration\nsidebar_label: NestJS\n---\n\nTypeGraphQL provides some basic integration with NestJS by the [`typegraphql-nestjs` package](https://www.npmjs.com/package/typegraphql-nestjs).\n\nIt allows to use TypeGraphQL features while integrating with NestJS modules system and its dependency injector.\n\n## Overview\n\nThe usage is similar to the official `@nestjs/graphql` package.\nFirst you need to register your resolver classes in `providers` of the `@Module` :\n\n```ts\n@Module({\n  providers: [RecipeResolver, RecipeService],\n})\nexport default class RecipeModule {}\n```\n\nThen you need to register the TypeGraphQL module in your root module - you can pass there all standard `buildSchema` options:\n\n```ts\n@Module({\n  imports: [\n    TypeGraphQLModule.forRoot({\n      emitSchemaFile: true,\n      authChecker,\n      context: ({ req }) => ({ currentUser: req.user }),\n    }),\n    RecipeModule,\n  ],\n})\nexport default class AppModule {}\n```\n\nAnd your `AppModule` is ready to use like with a standard NestJS approach.\n\n### Caveats\n\nFor now, this basic integration doesn't support other NestJS features like guards, interceptors, filters and pipes.\nTo achieve the same goals, you can use standard TypeGraphQL equivalents - middlewares, custom decorators, built-in authorization and validation.\n\n## Documentation and examples\n\nYou 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).\n"
  },
  {
    "path": "docs/performance.md",
    "content": "---\ntitle: Performance\n---\n\n**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.\n\nWhile this enable easy and convenient development, it's sometimes a tradeoff in a performance.\n\n## Benchmarks\n\nTo 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).\n\nThe most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower.\n\n|                      | 25 000 array items | Deeply nested object |\n| -------------------- | :----------------: | :------------------: |\n| Standard TypeGraphQL |     1253.28 ms     |       45.57 μs       |\n| `graphql-js`         |     265.52 ms      |       24.22 μs       |\n\nIn 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.\n\n## Optimizations\n\nPromises 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`.\n\n| `graphql-js`    | 25 000 array items |\n| --------------- | :----------------: |\n| sync resolvers  |     265.52 ms      |\n| async resolvers |     512.61 ms      |\n\nTypeGraphQL 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.\n\nAlso, 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).\n\nThe 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!\n\n## Further performance tweaks\n\nWhen 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.:\n\n```ts\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField: string;\n\n  @Field({ simple: true })\n  publicFrequentlyQueriedField: SomeType;\n}\n```\n\nMoreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.:\n\n```ts\n@ObjectType({ simpleResolvers: true })\nclass Post {\n  @Field()\n  title: string;\n\n  @Field()\n  createdAt: Date;\n\n  @Field()\n  isPublished: boolean;\n}\n```\n\nThis 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):\n\n|                                                                          | 25 000 array items |\n| ------------------------------------------------------------------------ | :----------------: |\n| `graphql-js`                                                             |     265.52 ms      |\n| Standard TypeGraphQL                                                     |     310.36 ms      |\n| TypeGraphQL with a global middleware                                     |     1253.28 ms     |\n| **TypeGraphQL with \"simpleResolvers\" applied (and a global middleware)** |   **299.61 ms**    |\n\n> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature.\n\nBy 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.\n\nThat'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.\n"
  },
  {
    "path": "docs/prisma.md",
    "content": "---\ntitle: Prisma Integration\nsidebar_label: Prisma\n---\n\nTypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma).\n\nIt 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.\n\n## Overview\n\nTo make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file:\n\n```sh\ngenerator typegraphql {\n  provider = \"typegraphql-prisma\"\n}\n```\n\nThen, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema:\n\n```ts\nimport { resolvers } from \"@generated/type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  validate: false,\n});\n```\n\nSo we will be able to execute a complex query, that talks with the real database, in just a few minutes!\n\n```graphql\nquery GetSomeUsers {\n  users(where: { email: { contains: \"prisma\" } }, orderBy: { name: desc }) {\n    id\n    name\n    email\n    posts(take: 10, orderBy: { updatedAt: desc }) {\n      published\n      title\n      content\n    }\n  }\n}\n```\n\n## Documentation and examples\n\nTo 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).\n\nThere also can be found the links to some examples and more detailed info about the installation and the configuration.\n"
  },
  {
    "path": "docs/resolvers.md",
    "content": "---\ntitle: Resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/master/examples).\n"
  },
  {
    "path": "docs/scalars.md",
    "content": "---\ntitle: Scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field types:\n\n```ts\n// Import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```ts\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```ts\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  // TS reflected type is `Object` :(\n  get optionalInfo(): string | undefined {\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Custom Scalars\n\nTypeGraphQL also supports custom scalar types!\n\nFirst 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:\n\n```ts\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  serialize(value: unknown): string {\n    // Check type of value\n    if (!(value instanceof ObjectId)) {\n      throw new Error(\"ObjectIdScalar can only serialize ObjectId values\");\n    }\n    return value.toHexString(); // Value sent to client\n  },\n  parseValue(value: unknown): ObjectId {\n    // Check type of value\n    if (typeof value !== \"string\") {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(value); // Value from client input variables\n  },\n  parseLiteral(ast): ObjectId {\n    // Check type of value\n    if (ast.kind !== Kind.STRING) {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(ast.value); // Value from client query\n  },\n});\n```\n\nThen we can just use it in our field decorators:\n\n```ts\n// Import earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // Explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!):\n\n```ts\n@ObjectType()\nclass User {\n  @Field() // Magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll we need to do is register the association map in the `buildSchema` options:\n\n```ts\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- ISO-formatted string: `\"2023-05-19T21:04:39.573Z\"`\n- timestamp-based number: `1518037458374`\n\nThey are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp` but comes from `graphql-scalars` npm package.\n\nBy default, TypeGraphQL uses the ISO date format, however we can change it to timestamp format using the mentioned above `scalarsMap` option of `buildSchema` configuration:\n\n```ts\nimport { buildSchema, GraphQLTimestamp } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],\n});\n```\n\nThere's no need then to explicitly declare the field type:\n\n```ts\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\nWe can of course use any other `Date` scalar from `graphql-scalars` or any other npm package.\n"
  },
  {
    "path": "docs/subscriptions.md",
    "content": "---\ntitle: Subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscription`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ root, args, context, info }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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/subscription` package.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscription` package. Optionally, we can define the used topics and payload type using the type argument, e.g.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscription\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscription` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscription`, the second argument might be treated as a payload, not dynamic topic id.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscription` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee 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.\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "docs/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```ts\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```ts\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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])`.\nFor 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.\n\nWhy 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.\n\nBy 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).\n\nSo 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.\n\nIn 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\"`.\n\nFor 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]]!`\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```ts\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```ts\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n\nBe 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.\n\nIn some case we may want to expose our classes or properties under a different types or fields name.\nTo accomplish this, we can use the `name` parameter or `name` property of decorator's options, e.g.:\n\n```ts\n@ObjectType(\"ExternalTypeName\")\nclass InternalClassName {\n  @Field({ name: \"externalFieldName\" })\n  internalPropertyName: string;\n}\n```\n\nHowever, 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.\n"
  },
  {
    "path": "docs/unions.md",
    "content": "---\ntitle: Unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "docs/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/master/examples/custom-validation).\n"
  },
  {
    "path": "examples/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"no-console\": \"off\",\n    \"class-methods-use-this\": \"off\",\n    \"import/no-cycle\": \"off\",\n    \"import/no-extraneous-dependencies\": [\"error\", { \"devDependencies\": true }]\n  }\n}\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Examples\n\nThis folder consists of simple examples showing how to use different `TypeGraphQL` features and how well it integrates with 3rd party libraries.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n> **Note**: Be aware that the examples on master branch are designed to work with latest codebase that might not be released yet.\n> 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).\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](./simple-usage)\n\n## Advanced\n\n- [Enums and unions](./enums-and-unions)\n- [Subscriptions (simple)](./simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](./redis-subscriptions)\n- [Interfaces](./interfaces-inheritance)\n- [Extensions (metadata)](./extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](./using-container)\n  - [Scoped containers](./using-scoped-container)\n- [Authorization](./authorization)\n- [Validation](./automatic-validation)\n  - [Custom validation](./custom-validation)\n- [Types inheritance](./interfaces-inheritance)\n- [Resolvers inheritance](./resolvers-inheritance)\n- [Generic types](./generic-types)\n- [Mixin classes](./mixin-classes)\n- [Middlewares and custom decorators](./middlewares-custom-decorators)\n- [Query complexity](./query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](./typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](./typeorm-lazy-relations)\n- [MikroORM \\*](./mikro-orm)\n- [Typegoose \\*](./typegoose)\n- [Apollo Federation](./apollo-federation)\n- [Apollo Federation 2](./apollo-federation-2)\n- [Apollo Cache Control](./apollo-cache)\n- [GraphQL Scalars](./graphql-scalars)\n- [TSyringe](./tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "examples/apollo-cache/cache-control.ts",
    "content": "import { type CacheHint } from \"@apollo/cache-control-types\";\nimport { Directive } from \"type-graphql\";\nimport { type RequireAtLeastOne } from \"./helpers/RequireAtLeastOne\";\n\nexport function CacheControl({ maxAge, scope }: RequireAtLeastOne<CacheHint>) {\n  if (maxAge === undefined && scope === undefined) {\n    throw new Error(\"Missing maxAge or scope param for @CacheControl\");\n  }\n\n  let sdl = \"@cacheControl(\";\n  if (maxAge !== undefined) {\n    sdl += `maxAge: ${maxAge}`;\n  }\n  if (scope) {\n    sdl += ` scope: ${scope}`;\n  }\n  sdl += \")\";\n\n  return Directive(sdl);\n}\n"
  },
  {
    "path": "examples/apollo-cache/examples.graphql",
    "content": "query CachedQuery {\n  cachedRecipe(title: \"Recipe 1\") {\n    title\n    description\n    cachedAverageRating\n  }\n}\n\nquery NotCachedQuery {\n  recipe(title: \"Recipe 1\") {\n    title\n    description\n    averageRating\n  }\n}\n"
  },
  {
    "path": "examples/apollo-cache/helpers/RequireAtLeastOne.d.ts",
    "content": "// https://stackoverflow.com/a/49725198/6676781\n\nexport type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &\n  {\n    [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;\n  }[Keys];\n"
  },
  {
    "path": "examples/apollo-cache/helpers/getTime.ts",
    "content": "export function getTime(date: Date = new Date()) {\n  return date.toTimeString().slice(0, 8);\n}\n"
  },
  {
    "path": "examples/apollo-cache/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { ApolloServerPluginCacheControl } from \"@apollo/server/plugin/cacheControl\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport responseCachePlugin from \"@apollo/server-plugin-response-cache\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    plugins: [\n      // Cache headers\n      ApolloServerPluginCacheControl(),\n      // In-memory cache\n      responseCachePlugin(),\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/apollo-cache/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>) {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport function createRecipeSamples() {\n  return [\n    createRecipe({\n      title: \"Recipe 1\",\n      description: \"Desc 1\",\n      ratings: [0, 3, 1],\n      creationDate: new Date(\"2018-04-11\"),\n    }),\n    createRecipe({\n      title: \"Recipe 2\",\n      description: \"Desc 2\",\n      ratings: [4, 2, 3, 1],\n      creationDate: new Date(\"2018-04-15\"),\n    }),\n    createRecipe({\n      title: \"Recipe 3\",\n      description: \"Desc 3\",\n      ratings: [5, 4],\n      creationDate: new Date(),\n    }),\n  ];\n}\n"
  },
  {
    "path": "examples/apollo-cache/recipe.resolver.ts",
    "content": "import { Arg, Query, Resolver } from \"type-graphql\";\nimport { CacheControl } from \"./cache-control\";\nimport { getTime } from \"./helpers/getTime\";\nimport { createRecipeSamples } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  private readonly items: Recipe[] = createRecipeSamples();\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"title\") title: string): Promise<Recipe | undefined> {\n    console.log(`Called 'recipe' with title '${title}' on ${getTime()}`);\n    return this.items.find(recipe => recipe.title === title);\n  }\n\n  @Query(_returns => Recipe, { nullable: true })\n  // Cache query for 60s\n  @CacheControl({ maxAge: 60 })\n  async cachedRecipe(@Arg(\"title\") title: string): Promise<Recipe | undefined> {\n    console.log(`Called 'cachedRecipe' with title '${title}' on ${getTime()}`);\n    return this.items.find(recipe => recipe.title === title);\n  }\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return this.items;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-cache/recipe.type.ts",
    "content": "import { Field, Float, Int, ObjectType } from \"type-graphql\";\nimport { CacheControl } from \"./cache-control\";\nimport { getTime } from \"./helpers/getTime\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Int])\n  ratings!: number[];\n\n  @Field()\n  creationDate!: Date;\n\n  @Field(_type => Float, { nullable: true })\n  // Invalidate 'cachedRecipe' cache with maxAge of 60 to 10 (if requested)\n  @CacheControl({ maxAge: 10 })\n  get cachedAverageRating() {\n    console.log(`Called 'cachedAverageRating' for recipe '${this.title}' on ${getTime()}`);\n    return this.averageRating;\n  }\n\n  @Field(_type => Float, { nullable: true })\n  get averageRating(): number | null {\n    console.log(`Called 'averageRating' for recipe '${this.title}' on ${getTime()}`);\n    const ratingsCount = this.ratings.length;\n    if (ratingsCount === 0) {\n      return null;\n    }\n    const ratingsSum = this.ratings.reduce((a, b) => a + b, 0);\n\n    return ratingsSum / ratingsCount;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-cache/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Query {\n  cachedRecipe(title: String!): Recipe\n  recipe(title: String!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float\n  cachedAverageRating: Float\n  creationDate: DateTimeISO!\n  description: String\n  ratings: [Int!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/apollo-federation/accounts/data.ts",
    "content": "import { User } from \"./user\";\n\nfunction createUser(userData: Partial<User>) {\n  return Object.assign(new User(), userData);\n}\n\nexport const users: User[] = [\n  createUser({\n    id: \"1\",\n    name: \"Ada Lovelace\",\n    birthDate: \"1815-12-10\",\n    username: \"@ada\",\n  }),\n  createUser({\n    id: \"2\",\n    name: \"Alan Turing\",\n    birthDate: \"1912-06-23\",\n    username: \"@complete\",\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation/accounts/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { AccountsResolver } from \"./resolver\";\nimport { User } from \"./user\";\nimport { resolveUserReference } from \"./user.reference\";\nimport { buildFederatedSchema } from \"../helpers\";\n\nexport async function listen(port: number): Promise<string> {\n  // Build TypeGraphQL executable schema\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [AccountsResolver],\n      orphanedTypes: [User],\n    },\n    {\n      User: { __resolveReference: resolveUserReference },\n    },\n  );\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Accounts service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation/accounts/resolver.ts",
    "content": "import { Query, Resolver } from \"type-graphql\";\nimport { users } from \"./data\";\nimport { User } from \"./user\";\n\n@Resolver(_of => User)\nexport class AccountsResolver {\n  @Query(_returns => User)\n  me(): User {\n    return users[0];\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/accounts/user.reference.ts",
    "content": "import { users } from \"./data\";\nimport { type User } from \"./user\";\n\nexport async function resolveUserReference(reference: Pick<User, \"id\">): Promise<User> {\n  return users.find(u => u.id === reference.id)!;\n}\n"
  },
  {
    "path": "examples/apollo-federation/accounts/user.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\n\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class User {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  username!: string;\n\n  @Field()\n  name!: string;\n\n  @Field()\n  birthDate!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation/examples.graphql",
    "content": "query {\n  topProducts {\n    name\n    price\n    shippingEstimate\n    inStock\n    reviews {\n      body\n      author {\n        name\n        birthDate\n        reviews {\n          product {\n            name\n          }\n          body\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/helpers/buildFederatedSchema.ts",
    "content": "import { buildSubgraphSchema } from \"@apollo/subgraph\";\nimport { type IResolvers, printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport gql from \"graphql-tag\";\nimport deepMerge from \"lodash.merge\";\nimport { type BuildSchemaOptions, buildSchema, createResolversMap } from \"type-graphql\";\n\nexport async function buildFederatedSchema(\n  options: Omit<BuildSchemaOptions, \"skipCheck\">,\n  referenceResolvers?: IResolvers,\n) {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    ...options,\n    // Disable check to allow schemas without query, etc...\n    skipCheck: true,\n  });\n\n  // Build Apollo Subgraph schema\n  const federatedSchema = buildSubgraphSchema({\n    typeDefs: gql(printSchemaWithDirectives(schema)),\n    // Merge schema's resolvers with reference resolvers\n    resolvers: deepMerge(createResolversMap(schema) as any, referenceResolvers),\n  });\n\n  return federatedSchema;\n}\n"
  },
  {
    "path": "examples/apollo-federation/helpers/index.ts",
    "content": "export * from \"./buildFederatedSchema\";\n"
  },
  {
    "path": "examples/apollo-federation/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloGateway, IntrospectAndCompose } from \"@apollo/gateway\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\nimport * as accounts from \"./accounts\";\nimport * as inventory from \"./inventory\";\nimport * as products from \"./products\";\nimport * as reviews from \"./reviews\";\n\nasync function bootstrap() {\n  const gateway = new ApolloGateway({\n    supergraphSdl: new IntrospectAndCompose({\n      subgraphs: [\n        { name: \"accounts\", url: await accounts.listen(4001) },\n        { name: \"reviews\", url: await reviews.listen(4002) },\n        { name: \"products\", url: await products.listen(4003) },\n        { name: \"inventory\", url: await inventory.listen(4004) },\n      ],\n    }),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ gateway });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`Apollo Gateway ready at ${url}`);\n\n  // Create 'schema.graphql' file with schema definition in current directory\n  await emitSchemaDefinitionFile(path.resolve(__dirname, \"schema.graphql\"), gateway.schema!);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/apollo-federation/inventory/data.ts",
    "content": "export interface Inventory {\n  upc: string;\n  inStock: boolean;\n}\n\nexport const inventory: Inventory[] = [\n  { upc: \"1\", inStock: true },\n  { upc: \"2\", inStock: false },\n  { upc: \"3\", inStock: true },\n];\n"
  },
  {
    "path": "examples/apollo-federation/inventory/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product } from \"./product\";\nimport { resolveProductReference } from \"./product.reference\";\nimport { InventoryResolver } from \"./resolver\";\nimport { buildFederatedSchema } from \"../helpers\";\n\nexport async function listen(port: number): Promise<string> {\n  // Build TypeGraphQL executable schema\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [InventoryResolver],\n      orphanedTypes: [Product],\n    },\n    {\n      Product: { __resolveReference: resolveProductReference },\n    },\n  );\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Inventory service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation/inventory/product.reference.ts",
    "content": "import { inventory } from \"./data\";\nimport { Product } from \"./product\";\n\nexport async function resolveProductReference(\n  reference: Pick<Product, \"upc\">,\n): Promise<Product | undefined> {\n  const found = inventory.find(i => i.upc === reference.upc);\n\n  if (!found) {\n    return;\n  }\n\n  // eslint-disable-next-line consistent-return\n  return Object.assign(new Product(), {\n    ...reference,\n    ...found,\n  });\n}\n"
  },
  {
    "path": "examples/apollo-federation/inventory/product.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\n@Directive(\"@extends\")\n@Directive(`@key(fields: \"upc\")`)\nexport class Product {\n  @Field()\n  @Directive(\"@external\")\n  upc!: string;\n\n  @Field()\n  @Directive(\"@external\")\n  weight!: number;\n\n  @Field()\n  @Directive(\"@external\")\n  price!: number;\n\n  @Field()\n  inStock!: boolean;\n}\n"
  },
  {
    "path": "examples/apollo-federation/inventory/resolver.ts",
    "content": "import { Directive, FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Product } from \"./product\";\n\n@Resolver(_of => Product)\nexport class InventoryResolver {\n  @Directive(`@requires(fields: \"price weight\")`)\n  @FieldResolver(_returns => Number)\n  async shippingEstimate(@Root() product: Product): Promise<number> {\n    // Free for expensive items\n    if (product.price > 1000) {\n      return 0;\n    }\n\n    // Estimate is based on weight\n    return product.weight * 0.5;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/products/data.ts",
    "content": "import { Product } from \"./product\";\n\nfunction createProduct(productData: Partial<Product>) {\n  return Object.assign(new Product(), productData);\n}\n\nexport const products: Product[] = [\n  createProduct({\n    upc: \"1\",\n    name: \"Table\",\n    price: 899,\n    weight: 100,\n  }),\n  createProduct({\n    upc: \"2\",\n    name: \"Couch\",\n    price: 1299,\n    weight: 1000,\n  }),\n  createProduct({\n    upc: \"3\",\n    name: \"Chair\",\n    price: 54,\n    weight: 50,\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation/products/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product } from \"./product\";\nimport { resolveProductReference } from \"./product.reference\";\nimport { ProductsResolver } from \"./resolver\";\nimport { buildFederatedSchema } from \"../helpers\";\n\nexport async function listen(port: number): Promise<string> {\n  // Build TypeGraphQL executable schema\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [ProductsResolver],\n      orphanedTypes: [Product],\n    },\n    {\n      Product: { __resolveReference: resolveProductReference },\n    },\n  );\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Products service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation/products/product.reference.ts",
    "content": "import { products } from \"./data\";\nimport { type Product } from \"./product\";\n\nexport async function resolveProductReference(\n  reference: Pick<Product, \"upc\">,\n): Promise<Product | undefined> {\n  return products.find(p => p.upc === reference.upc);\n}\n"
  },
  {
    "path": "examples/apollo-federation/products/product.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\n\n@Directive(`@key(fields: \"upc\")`)\n@ObjectType()\nexport class Product {\n  @Field()\n  upc!: string;\n\n  @Field()\n  name!: string;\n\n  @Field()\n  price!: number;\n\n  @Field()\n  weight!: number;\n}\n"
  },
  {
    "path": "examples/apollo-federation/products/resolver.ts",
    "content": "import { Arg, Query, Resolver } from \"type-graphql\";\nimport { products } from \"./data\";\nimport { Product } from \"./product\";\n\n@Resolver(_of => Product)\nexport class ProductsResolver {\n  @Query(_returns => [Product])\n  async topProducts(\n    @Arg(\"first\", { defaultValue: 5 })\n    first: number,\n  ): Promise<Product[]> {\n    return products.slice(0, first);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product, ProductReviewsResolver } from \"./product\";\nimport { Review, ReviewsResolver } from \"./review\";\nimport { User, UserReviewsResolver } from \"./user\";\nimport { buildFederatedSchema } from \"../helpers\";\n\nexport async function listen(port: number): Promise<string> {\n  // Build TypeGraphQL executable schema\n  const schema = await buildFederatedSchema({\n    resolvers: [ReviewsResolver, ProductReviewsResolver, UserReviewsResolver],\n    orphanedTypes: [User, Review, Product],\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Reviews service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/product/index.ts",
    "content": "export * from \"./product\";\n\nexport * from \"./resolver\";\n"
  },
  {
    "path": "examples/apollo-federation/reviews/product/product.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\n\n@Directive(\"@extends\")\n@Directive(`@key(fields: \"upc\")`)\n@ObjectType()\nexport class Product {\n  @Directive(\"@external\")\n  @Field()\n  upc!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/product/resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Product } from \"./product\";\nimport { Review, reviews } from \"../review\";\n\n@Resolver(_of => Product)\nexport class ProductReviewsResolver {\n  @FieldResolver(() => [Review])\n  async reviews(@Root() product: Product): Promise<Review[]> {\n    return reviews.filter(review => review.product.upc === product.upc);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/review/data.ts",
    "content": "import { Review } from \"./review\";\nimport { Product } from \"../product\";\nimport { User } from \"../user\";\n\nfunction createReview(reviewData: Partial<Review>) {\n  return Object.assign(new Review(), reviewData);\n}\n\nfunction createUser(userData: Partial<User>) {\n  return Object.assign(new User(), userData);\n}\n\nfunction createProduct(productData: Partial<Product>) {\n  return Object.assign(new Product(), productData);\n}\n\nexport const reviews: Review[] = [\n  createReview({\n    id: \"1\",\n    author: createUser({\n      id: \"1\",\n      username: \"@ada\",\n    }),\n    product: createProduct({\n      upc: \"1\",\n    }),\n    body: \"Love it!\",\n  }),\n  createReview({\n    id: \"2\",\n    author: createUser({\n      id: \"1\",\n      username: \"@ada\",\n    }),\n    product: createProduct({\n      upc: \"2\",\n    }),\n    body: \"Too expensive.\",\n  }),\n  createReview({\n    id: \"3\",\n    author: createUser({\n      id: \"2\",\n      username: \"@complete\",\n    }),\n    product: createProduct({\n      upc: \"3\",\n    }),\n    body: \"Could be better.\",\n  }),\n  createReview({\n    id: \"4\",\n    author: createUser({\n      id: \"2\",\n      username: \"@complete\",\n    }),\n    product: createProduct({\n      upc: \"1\",\n    }),\n    body: \"Prefer something else.\",\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation/reviews/review/index.ts",
    "content": "export * from \"./data\";\nexport * from \"./resolver\";\nexport * from \"./review\";\n"
  },
  {
    "path": "examples/apollo-federation/reviews/review/resolver.ts",
    "content": "import { FieldResolver, Resolver } from \"type-graphql\";\nimport { reviews } from \"./data\";\nimport { Review } from \"./review\";\n\n@Resolver(_of => Review)\nexport class ReviewsResolver {\n  @FieldResolver(_returns => [Review])\n  async reviews(): Promise<Review[]> {\n    return reviews;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/review/review.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\nimport { Product } from \"../product\";\nimport { User } from \"../user\";\n\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class Review {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  body!: string;\n\n  @Directive(`@provides(fields: \"username\")`)\n  @Field()\n  author!: User;\n\n  @Field()\n  product!: Product;\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/user/index.ts",
    "content": "export * from \"./resolver\";\nexport * from \"./user\";\n"
  },
  {
    "path": "examples/apollo-federation/reviews/user/resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { User } from \"./user\";\nimport { Review, reviews } from \"../review\";\n\n@Resolver(_of => User)\nexport class UserReviewsResolver {\n  @FieldResolver(_returns => [Review])\n  async reviews(@Root() user: User): Promise<Review[]> {\n    return reviews.filter(review => review.author.id === user.id);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation/reviews/user/user.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\n\n@Directive(\"@extends\")\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class User {\n  @Directive(\"@external\")\n  @Field(_type => ID)\n  id!: string;\n\n  @Directive(\"@external\")\n  @Field()\n  username!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Product {\n  inStock: Boolean!\n  name: String!\n  price: Float!\n  reviews: [Review!]!\n  shippingEstimate: Float!\n  upc: String!\n  weight: Float!\n}\n\ntype Query {\n  me: User!\n  topProducts(first: Float! = 5): [Product!]!\n}\n\ntype Review {\n  author: User!\n  body: String!\n  id: ID!\n  product: Product!\n  reviews: [Review!]!\n}\n\ntype User {\n  birthDate: String!\n  id: ID!\n  name: String!\n  reviews: [Review!]!\n  username: String!\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/accounts/data.ts",
    "content": "import { User } from \"./user\";\n\nfunction createUser(userData: Partial<User>) {\n  return Object.assign(new User(), userData);\n}\n\nexport const users: User[] = [\n  createUser({\n    id: \"1\",\n    name: \"Ada Lovelace\",\n    birthDate: \"1815-12-10\",\n    username: \"@ada\",\n  }),\n  createUser({\n    id: \"2\",\n    name: \"Alan Turing\",\n    birthDate: \"1912-06-23\",\n    username: \"@complete\",\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation-2/accounts/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { AccountsResolver } from \"./resolver\";\nimport { User } from \"./user\";\nimport { resolveUserReference } from \"./user.reference\";\nimport { buildFederatedSchema } from \"../helpers/buildFederatedSchema\";\n\nexport async function listen(port: number): Promise<string> {\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [AccountsResolver],\n      orphanedTypes: [User],\n    },\n    {\n      User: { __resolveReference: resolveUserReference },\n    },\n  );\n\n  const server = new ApolloServer({ schema });\n\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Accounts service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/accounts/resolver.ts",
    "content": "import { Query, Resolver } from \"type-graphql\";\nimport { users } from \"./data\";\nimport { User } from \"./user\";\n\n@Resolver(_of => User)\nexport class AccountsResolver {\n  @Query(_returns => User)\n  me(): User {\n    return users[0];\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/accounts/user.reference.ts",
    "content": "import { users } from \"./data\";\nimport { type User } from \"./user\";\n\nexport async function resolveUserReference(reference: Pick<User, \"id\">): Promise<User> {\n  return users.find(u => u.id === reference.id)!;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/accounts/user.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\n\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class User {\n  @Field(_type => ID)\n  id!: string;\n\n  @Directive(\"@shareable\")\n  @Field()\n  username!: string;\n\n  @Field()\n  name!: string;\n\n  @Field()\n  birthDate!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/examples.graphql",
    "content": "query {\n  topProducts {\n    __typename\n    name\n    price\n    shippingEstimate\n    inStock\n    reviews {\n      body\n      author {\n        name\n        birthDate\n        reviews {\n          product {\n            __typename\n            name\n          }\n          body\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/helpers/buildFederatedSchema.ts",
    "content": "import { buildSubgraphSchema } from \"@apollo/subgraph\";\nimport { type IResolvers, printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport gql from \"graphql-tag\";\nimport deepMerge from \"lodash.merge\";\nimport { type BuildSchemaOptions, buildSchema, createResolversMap } from \"type-graphql\";\n\nexport async function buildFederatedSchema(\n  options: Omit<BuildSchemaOptions, \"skipCheck\">,\n  referenceResolvers?: IResolvers,\n) {\n  // build TypeGraphQL schema\n  const schema = await buildSchema({\n    ...options,\n    skipCheck: true, // disable check to allow schemas without query, etc.\n  });\n\n  // build Apollo Subgraph schema\n  const federatedSchema = buildSubgraphSchema({\n    typeDefs: gql`\n      extend schema\n        @link(\n          url: \"https://specs.apollo.dev/federation/v2.3\"\n          import: [\n            \"@key\"\n            \"@shareable\"\n            \"@provides\"\n            \"@extends\"\n            \"@requires\"\n            \"@external\"\n            \"@interfaceObject\"\n          ]\n        )\n      ${printSchemaWithDirectives(schema)}\n    `,\n    // merge schema's resolvers with reference resolvers\n    resolvers: deepMerge(createResolversMap(schema) as any, referenceResolvers),\n  });\n\n  return federatedSchema;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"path\";\nimport { ApolloGateway, IntrospectAndCompose } from \"@apollo/gateway\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\nimport * as accounts from \"./accounts\";\nimport * as inventory from \"./inventory\";\nimport * as products from \"./products\";\nimport * as reviews from \"./reviews\";\n\nconst startGraph = async (name: string, urlOrPromise: string | Promise<string>) => {\n  const url = await urlOrPromise;\n  return { name, url };\n};\n\nasync function bootstrap() {\n  const subgraphs = await Promise.all([\n    startGraph(\"accounts\", accounts.listen(4001)),\n    startGraph(\"reviews\", reviews.listen(4002)),\n    startGraph(\"products\", products.listen(4003)),\n    startGraph(\"inventory\", inventory.listen(4004)),\n  ]);\n\n  const schemaGateway = new ApolloGateway({\n    supergraphSdl: new IntrospectAndCompose({\n      subgraphs,\n    }),\n  });\n  const { schema } = await schemaGateway.load();\n  await emitSchemaDefinitionFile(path.resolve(__dirname, \"schema.graphql\"), schema);\n  await schemaGateway.stop();\n\n  const gateway = new ApolloGateway({\n    supergraphSdl: new IntrospectAndCompose({\n      subgraphs,\n    }),\n  });\n  const server = new ApolloServer({ gateway });\n\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n\n  console.log(`Apollo Gateway ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/apollo-federation-2/inventory/data.ts",
    "content": "export interface Inventory {\n  upc: string;\n  inStock: boolean;\n}\n\nexport const inventory: Inventory[] = [\n  { upc: \"1\", inStock: true },\n  { upc: \"2\", inStock: false },\n  { upc: \"3\", inStock: true },\n];\n"
  },
  {
    "path": "examples/apollo-federation-2/inventory/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product } from \"./product\";\nimport { resolveProductReference } from \"./product.reference\";\nimport { InventoryResolver } from \"./resolver\";\nimport { buildFederatedSchema } from \"../helpers/buildFederatedSchema\";\n\nexport async function listen(port: number): Promise<string> {\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [InventoryResolver],\n      orphanedTypes: [Product],\n    },\n    {\n      Product: { __resolveReference: resolveProductReference },\n    },\n  );\n\n  const server = new ApolloServer({ schema });\n\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Inventory service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/inventory/product.reference.ts",
    "content": "import { inventory } from \"./data\";\nimport { Product } from \"./product\";\n\nexport async function resolveProductReference(\n  reference: Pick<Product, \"upc\">,\n): Promise<Product | undefined> {\n  const found = inventory.find(i => i.upc === reference.upc);\n\n  if (!found) {\n    return undefined;\n  }\n\n  return Object.assign(new Product(), {\n    ...reference,\n    ...found,\n  });\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/inventory/product.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\n@Directive(\"@extends\")\n@Directive(\"@interfaceObject\")\n@Directive(`@key(fields: \"upc\")`)\nexport class Product {\n  @Field()\n  @Directive(\"@external\")\n  upc!: string;\n\n  @Field()\n  @Directive(\"@external\")\n  weight!: number;\n\n  @Field()\n  @Directive(\"@external\")\n  price!: number;\n\n  @Field()\n  inStock!: boolean;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/inventory/resolver.ts",
    "content": "import { Directive, FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Product } from \"./product\";\n\n@Resolver(_of => Product)\nexport class InventoryResolver {\n  @Directive(`@requires(fields: \"price weight\")`)\n  @FieldResolver(_returns => Number)\n  async shippingEstimate(@Root() product: Product): Promise<number> {\n    // free for expensive items\n    if (product.price > 1000) {\n      return 0;\n    }\n\n    // estimate is based on weight\n    return product.weight * 0.5;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/data.ts",
    "content": "import { Dining } from \"./dining\";\nimport { type Product } from \"./product\";\nimport { Seating } from \"./seating\";\n\nexport const products: Product[] = [\n  Object.assign(new Dining(), {\n    upc: \"1\",\n    name: \"Table\",\n    price: 899,\n    weight: 100,\n    height: \"3ft\",\n  }),\n  Object.assign(new Seating(), {\n    upc: \"2\",\n    name: \"Couch\",\n    price: 1299,\n    weight: 1000,\n    seats: 2,\n  }),\n  Object.assign(new Seating(), {\n    upc: \"3\",\n    name: \"Chair\",\n    price: 54,\n    weight: 50,\n    seats: 1,\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation-2/products/dining.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\nimport { Product } from \"./product\";\n\n@Directive(`@key(fields: \"upc\")`)\n@ObjectType({ implements: Product })\nexport class Dining extends Product {\n  @Field()\n  height!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product } from \"./product\";\nimport { resolveProductReference } from \"./product.reference\";\nimport { ProductsResolver } from \"./resolver\";\nimport { buildFederatedSchema } from \"../helpers/buildFederatedSchema\";\n\nexport async function listen(port: number): Promise<string> {\n  const schema = await buildFederatedSchema(\n    {\n      resolvers: [ProductsResolver],\n      orphanedTypes: [Product],\n    },\n    {\n      Product: { __resolveReference: resolveProductReference },\n    },\n  );\n\n  const server = new ApolloServer({ schema });\n\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Products service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/product.reference.ts",
    "content": "import { products } from \"./data\";\nimport { type Product } from \"./product\";\n\nexport async function resolveProductReference(\n  reference: Pick<Product, \"upc\">,\n): Promise<Product | undefined> {\n  return products.find(p => p.upc === reference.upc);\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/product.ts",
    "content": "import { Directive, Field, InterfaceType } from \"type-graphql\";\n\n@Directive(`@key(fields: \"upc\")`)\n@InterfaceType()\nexport abstract class Product {\n  @Field()\n  upc!: string;\n\n  @Field()\n  name!: string;\n\n  @Field()\n  price!: number;\n\n  @Field()\n  weight!: number;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/resolver.ts",
    "content": "import { Arg, Query, Resolver } from \"type-graphql\";\nimport { products } from \"./data\";\nimport { Product } from \"./product\";\n\n@Resolver(_of => Product)\nexport class ProductsResolver {\n  @Query(_returns => [Product])\n  async topProducts(\n    @Arg(\"first\", { defaultValue: 5 })\n    first: number,\n  ): Promise<Product[]> {\n    return products.slice(0, first);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/products/seating.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\nimport { Product } from \"./product\";\n\n@Directive(`@key(fields: \"upc\")`)\n@ObjectType({ implements: Product })\nexport class Seating extends Product {\n  @Field()\n  seats!: number;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/index.ts",
    "content": "import { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Product } from \"./product/product\";\nimport { ProductReviewsResolver } from \"./product/resolver\";\nimport { ReviewsResolver } from \"./review/resolver\";\nimport { Review } from \"./review/review\";\nimport { UserReviewsResolver } from \"./user/resolver\";\nimport { User } from \"./user/user\";\nimport { buildFederatedSchema } from \"../helpers/buildFederatedSchema\";\n\nexport async function listen(port: number): Promise<string> {\n  const schema = await buildFederatedSchema({\n    resolvers: [ReviewsResolver, ProductReviewsResolver, UserReviewsResolver],\n    orphanedTypes: [User, Review, Product],\n  });\n\n  const server = new ApolloServer({ schema });\n\n  const { url } = await startStandaloneServer(server, { listen: { port } });\n  console.log(`Reviews service ready at ${url}`);\n\n  return url;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/product/product.ts",
    "content": "import { Directive, Field, ObjectType } from \"type-graphql\";\n\n@Directive(\"@extends\")\n@Directive(`@key(fields: \"upc\")`)\n@Directive(\"@interfaceObject\")\n@ObjectType()\nexport class Product {\n  @Directive(\"@external\")\n  @Field()\n  upc!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/product/resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Product } from \"./product\";\nimport { reviews } from \"../review/data\";\nimport { Review } from \"../review/review\";\n\n@Resolver(_of => Product)\nexport class ProductReviewsResolver {\n  @FieldResolver(() => [Review])\n  async reviews(@Root() product: Product): Promise<Review[]> {\n    return reviews.filter(review => review.product.upc === product.upc);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/review/data.ts",
    "content": "import { Review } from \"./review\";\nimport { Product } from \"../product/product\";\nimport { User } from \"../user/user\";\n\nfunction createReview(reviewData: Partial<Review>) {\n  return Object.assign(new Review(), reviewData);\n}\n\nfunction createUser(userData: Partial<User>) {\n  return Object.assign(new User(), userData);\n}\n\nfunction createProduct(productData: Partial<Product>) {\n  return Object.assign(new Product(), productData);\n}\n\nexport const reviews: Review[] = [\n  createReview({\n    id: \"1\",\n    author: createUser({\n      id: \"1\",\n      username: \"@ada\",\n    }),\n    product: createProduct({\n      upc: \"1\",\n    }),\n    body: \"Love it!\",\n  }),\n  createReview({\n    id: \"2\",\n    author: createUser({\n      id: \"1\",\n      username: \"@ada\",\n    }),\n    product: createProduct({\n      upc: \"2\",\n    }),\n    body: \"Too expensive.\",\n  }),\n  createReview({\n    id: \"3\",\n    author: createUser({\n      id: \"2\",\n      username: \"@complete\",\n    }),\n    product: createProduct({\n      upc: \"3\",\n    }),\n    body: \"Could be better.\",\n  }),\n  createReview({\n    id: \"4\",\n    author: createUser({\n      id: \"2\",\n      username: \"@complete\",\n    }),\n    product: createProduct({\n      upc: \"1\",\n    }),\n    body: \"Prefer something else.\",\n  }),\n];\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/review/resolver.ts",
    "content": "import { FieldResolver, Resolver } from \"type-graphql\";\nimport { reviews } from \"./data\";\nimport { Review } from \"./review\";\n\n@Resolver(_of => Review)\nexport class ReviewsResolver {\n  @FieldResolver(_returns => [Review])\n  async reviews(): Promise<Review[]> {\n    return reviews;\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/review/review.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\nimport { Product } from \"../product/product\";\nimport { User } from \"../user/user\";\n\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class Review {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  body!: string;\n\n  @Directive(`@provides(fields: \"username\")`)\n  @Field()\n  author!: User;\n\n  @Field()\n  product!: Product;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/user/resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { User } from \"./user\";\nimport { reviews } from \"../review/data\";\nimport { Review } from \"../review/review\";\n\n@Resolver(_of => User)\nexport class UserReviewsResolver {\n  @FieldResolver(_returns => [Review])\n  async reviews(@Root() user: User): Promise<Review[]> {\n    return reviews.filter(review => review.author.id === user.id);\n  }\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/reviews/user/user.ts",
    "content": "import { Directive, Field, ID, ObjectType } from \"type-graphql\";\n\n@Directive(`@key(fields: \"id\")`)\n@ObjectType()\nexport class User {\n  @Field(_type => ID)\n  id!: string;\n\n  @Directive(\"@external\")\n  @Field()\n  username!: string;\n}\n"
  },
  {
    "path": "examples/apollo-federation-2/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Dining implements Product {\n  height: String!\n  inStock: Boolean!\n  name: String!\n  price: Float!\n  reviews: [Review!]!\n  shippingEstimate: Float!\n  upc: String!\n  weight: Float!\n}\n\ninterface Product {\n  inStock: Boolean!\n  name: String!\n  price: Float!\n  reviews: [Review!]!\n  shippingEstimate: Float!\n  upc: String!\n  weight: Float!\n}\n\ntype Query {\n  me: User!\n  topProducts(first: Float! = 5): [Product!]!\n}\n\ntype Review {\n  author: User!\n  body: String!\n  id: ID!\n  product: Product!\n  reviews: [Review!]!\n}\n\ntype Seating implements Product {\n  inStock: Boolean!\n  name: String!\n  price: Float!\n  reviews: [Review!]!\n  seats: Float!\n  shippingEstimate: Float!\n  upc: String!\n  weight: Float!\n}\n\ntype User {\n  birthDate: String!\n  id: ID!\n  name: String!\n  reviews: [Review!]!\n  username: String!\n}\n"
  },
  {
    "path": "examples/authorization/auth-checker.ts",
    "content": "import { type AuthChecker } from \"type-graphql\";\nimport { type Context } from \"./context.type\";\n\n// Auth checker function\nexport const authChecker: AuthChecker<Context> = ({ context: { user } }, roles) => {\n  // Check user\n  if (!user) {\n    // No user, restrict access\n    return false;\n  }\n\n  // Check '@Authorized()'\n  if (roles.length === 0) {\n    // Only authentication required\n    return true;\n  }\n\n  // Check '@Authorized(...)' roles overlap\n  return user.roles.some(role => roles.includes(role));\n};\n"
  },
  {
    "path": "examples/authorization/context.type.ts",
    "content": "import { type User } from \"./user.type\";\n\nexport interface Context {\n  user?: User;\n}\n"
  },
  {
    "path": "examples/authorization/examples.graphql",
    "content": "query GetPublicRecipes {\n  recipes {\n    title\n    description\n    averageRating\n  }\n}\n\nquery GetRecipesForAuthorizedUser {\n  recipes {\n    title\n    description\n    ingredients\n    averageRating\n  }\n}\n\nquery GetRecipesForAdmin {\n  recipes {\n    title\n    description\n    ingredients\n    averageRating\n    ratings\n  }\n}\n\nmutation AddRecipeByAuthorizedUser {\n  addRecipe(title: \"Sample Recipe\") {\n    averageRating\n  }\n}\n\nmutation DeleteRecipeByAdmin {\n  deleteRecipe(title: \"Recipe 1\")\n}\n"
  },
  {
    "path": "examples/authorization/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { authChecker } from \"./auth-checker\";\nimport { type Context } from \"./context.type\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Register auth checker function\n    authChecker,\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    // Provide context for each request\n    context: async () => ({\n      // Create mocked user in context\n      // In real app you would be mapping user from 'req.user' or sth\n      user: {\n        id: 1,\n        name: \"Sample user\",\n        roles: [\"REGULAR\"],\n      },\n    }),\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/authorization/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    ingredients: [\"one\", \"two\", \"three\"],\n    ratings: [3, 4, 5, 5, 5],\n  }),\n  createRecipe({\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    ingredients: [\"four\", \"five\", \"six\"],\n    ratings: [3, 4, 5, 3, 2],\n  }),\n  createRecipe({\n    title: \"Recipe 3\",\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n    ratings: [4, 4, 5, 5, 4],\n  }),\n];\n"
  },
  {
    "path": "examples/authorization/recipe.resolver.ts",
    "content": "import { Arg, Authorized, Mutation, Query, Resolver } from \"type-graphql\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver()\nexport class RecipeResolver {\n  private recipesData: Recipe[] = sampleRecipes.slice();\n\n  // Anyone can read recipes collection\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return this.recipesData;\n  }\n\n  @Authorized() // Only authenticated users can add new recipe\n  @Mutation()\n  addRecipe(\n    @Arg(\"title\") title: string,\n    @Arg(\"description\", { nullable: true }) description?: string,\n  ): Recipe {\n    const newRecipe = Object.assign(new Recipe(), {\n      title,\n      description,\n      ratings: [],\n    });\n    this.recipesData.push(newRecipe);\n\n    return newRecipe;\n  }\n\n  @Authorized(\"ADMIN\") // Only 'ADMIN' users can remove published recipe\n  @Mutation()\n  deleteRecipe(@Arg(\"title\") title: string): boolean {\n    const foundRecipeIndex = this.recipesData.findIndex(it => it.title === title);\n    if (!foundRecipeIndex) {\n      return false;\n    }\n    this.recipesData.splice(foundRecipeIndex, 1);\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "examples/authorization/recipe.type.ts",
    "content": "import { Authorized, Field, Float, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Authorized() // Restrict access only for authenticated users\n  @Field(_type => [String])\n  ingredients!: string[];\n\n  @Authorized(\"ADMIN\") // Restrict access only for 'ADMIN' users\n  @Field(_type => [Int])\n  ratings!: number[];\n\n  @Field(_type => Float, { nullable: true })\n  get averageRating(): number | null {\n    if (!this.ratings.length) {\n      return null;\n    }\n    return this.ratings.reduce((a, b) => a + b, 0) / this.ratings.length;\n  }\n}\n"
  },
  {
    "path": "examples/authorization/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(description: String, title: String!): Recipe!\n  deleteRecipe(title: String!): Boolean!\n}\n\ntype Query {\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float\n  description: String\n  ingredients: [String!]!\n  ratings: [Int!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/authorization/user.type.ts",
    "content": "export interface User {\n  id: number;\n  name: string;\n  roles: string[];\n}\n"
  },
  {
    "path": "examples/automatic-validation/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    title\n    description\n    creationDate\n  }\n}\n\nmutation CorrectAddRecipe {\n  addRecipe(\n    input: {\n      title: \"Correct title\"\n      description: \"Very very very very very very very very long description\"\n    }\n  ) {\n    creationDate\n  }\n}\n\nmutation AddRecipeWithoutDesc {\n  addRecipe(input: { title: \"Correct title\" }) {\n    creationDate\n  }\n}\n\nmutation IncorrectAddRecipe {\n  addRecipe(input: { title: \"Correct title\", description: \"Too short description\" }) {\n    creationDate\n  }\n}\n"
  },
  {
    "path": "examples/automatic-validation/helpers.ts",
    "content": "import { type Recipe } from \"./recipe.type\";\n\nexport function generateRecipes(count: number): Recipe[] {\n  return new Array(count).fill(null).map(\n    (_, i): Recipe => ({\n      title: `Recipe #${i + 1}`,\n      description: `Description #${i + 1}`,\n      creationDate: new Date(),\n    }),\n  );\n}\n"
  },
  {
    "path": "examples/automatic-validation/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // remember to turn on validation!\n    validate: true,\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/automatic-validation/recipe.input.ts",
    "content": "import { Length, MaxLength } from \"class-validator\";\nimport { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  @MaxLength(30)\n  title!: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n"
  },
  {
    "path": "examples/automatic-validation/recipe.resolver.ts",
    "content": "import { Arg, Args, Mutation, Query, Resolver } from \"type-graphql\";\nimport { generateRecipes } from \"./helpers\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\nimport { RecipesArguments } from \"./recipes.arguments\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  private readonly items: Recipe[] = generateRecipes(100);\n\n  @Query(_returns => [Recipe])\n  async recipes(@Args() options: RecipesArguments): Promise<Recipe[]> {\n    const start: number = options.skip;\n    const end: number = options.skip + options.take;\n    return this.items.slice(start, end);\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    const recipe = new Recipe();\n    recipe.description = recipeInput.description;\n    recipe.title = recipeInput.title;\n    recipe.creationDate = new Date();\n\n    await this.items.push(recipe);\n    return recipe;\n  }\n}\n"
  },
  {
    "path": "examples/automatic-validation/recipe.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate!: Date;\n}\n"
  },
  {
    "path": "examples/automatic-validation/recipes.arguments.ts",
    "content": "import { Max, Min } from \"class-validator\";\nimport { ArgsType, Field, Int } from \"type-graphql\";\n\n@ArgsType()\nexport class RecipesArguments {\n  @Field(_type => Int)\n  @Min(0)\n  skip = 0;\n\n  @Field(_type => Int)\n  @Min(1)\n  @Max(50)\n  take = 10;\n}\n"
  },
  {
    "path": "examples/automatic-validation/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(input: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]!\n}\n\ntype Recipe {\n  creationDate: DateTimeISO!\n  description: String\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n"
  },
  {
    "path": "examples/custom-validation/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    title\n    description\n    creationDate\n  }\n}\n\nmutation CorrectAddRecipe {\n  addRecipe(\n    input: {\n      title: \"Correct title\"\n      description: \"Very very very very very very very very long description\"\n    }\n  ) {\n    creationDate\n  }\n}\n\nmutation AddRecipeWithoutDesc {\n  addRecipe(input: { title: \"Correct title\" }) {\n    creationDate\n  }\n}\n\nmutation IncorrectAddRecipe {\n  addRecipe(input: { title: \"Correct title\", description: \"Too short description\" }) {\n    creationDate\n  }\n}\n"
  },
  {
    "path": "examples/custom-validation/helpers.ts",
    "content": "import { type Recipe } from \"./recipe.type\";\n\nexport function generateRecipes(count: number): Recipe[] {\n  return new Array(count).fill(null).map(\n    (_, i): Recipe => ({\n      title: `Recipe #${i + 1}`,\n      description: `Description #${i + 1}`,\n      creationDate: new Date(),\n    }),\n  );\n}\n"
  },
  {
    "path": "examples/custom-validation/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport joiful from \"joiful\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Custom validate function\n    validateFn: (argValue, _argType) => {\n      // Call joiful validate\n      const { error } = joiful.validate(argValue);\n      if (error) {\n        // Throw error if validation failed\n        throw error;\n      }\n    },\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/custom-validation/recipe.input.ts",
    "content": "import Joiful from \"joiful\";\nimport { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  // Joi decorator\n  @(Joiful.string().required().max(30))\n  title!: string;\n\n  @Field({ nullable: true })\n  // Joi decorator\n  @(Joiful.string().min(30).max(255))\n  description?: string;\n}\n"
  },
  {
    "path": "examples/custom-validation/recipe.resolver.ts",
    "content": "import { Arg, Args, Mutation, Query, Resolver } from \"type-graphql\";\nimport { generateRecipes } from \"./helpers\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\nimport { RecipesArguments } from \"./recipes.arguments\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  private readonly items: Recipe[] = generateRecipes(100);\n\n  @Query(_returns => [Recipe])\n  async recipes(@Args() options: RecipesArguments): Promise<Recipe[]> {\n    const start: number = options.skip;\n    const end: number = options.skip + options.take;\n    return this.items.slice(start, end);\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    const recipe = new Recipe();\n    recipe.description = recipeInput.description;\n    recipe.title = recipeInput.title;\n    recipe.creationDate = new Date();\n\n    await this.items.push(recipe);\n    return recipe;\n  }\n}\n"
  },
  {
    "path": "examples/custom-validation/recipe.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate!: Date;\n}\n"
  },
  {
    "path": "examples/custom-validation/recipes.arguments.ts",
    "content": "import Joiful from \"joiful\";\nimport { ArgsType, Field, Int } from \"type-graphql\";\n\n@ArgsType()\nexport class RecipesArguments {\n  @Field(_type => Int)\n  // use decorators for Joi\n  @(Joiful.number().min(0))\n  skip = 0;\n\n  @Field(_type => Int)\n  // use decorators for Joi\n  @(Joiful.number().min(1).max(50))\n  take = 10;\n}\n"
  },
  {
    "path": "examples/custom-validation/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nThe javascript `Date` as string. Type represents date and time as the ISO Date string.\n\"\"\"\nscalar DateTime\n\ntype Mutation {\n  addRecipe(input: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]!\n}\n\ntype Recipe {\n  creationDate: DateTime!\n  description: String\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n"
  },
  {
    "path": "examples/enums-and-unions/cook.data.ts",
    "content": "import { Cook } from \"./cook.type\";\n\nfunction createCook(cookData: Partial<Cook>): Cook {\n  return Object.assign(new Cook(), cookData);\n}\n\nexport const sampleCooks = [\n  createCook({\n    name: \"Gordon Ramsay\",\n    yearsOfExperience: 21,\n  }),\n  createCook({\n    name: \"Marilyn Monroe\",\n    yearsOfExperience: 1,\n  }),\n];\n"
  },
  {
    "path": "examples/enums-and-unions/cook.type.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Cook {\n  @Field()\n  name!: string;\n\n  @Field(_type => Int)\n  yearsOfExperience!: number;\n}\n"
  },
  {
    "path": "examples/enums-and-unions/difficulty.enum.ts",
    "content": "import { registerEnumType } from \"type-graphql\";\n\nexport enum Difficulty {\n  Beginner,\n  Easy,\n  Medium,\n  Hard,\n  MasterChef,\n}\n\nregisterEnumType(Difficulty, {\n  name: \"Difficulty\",\n  description: \"All possible preparation difficulty levels\",\n});\n"
  },
  {
    "path": "examples/enums-and-unions/examples.graphql",
    "content": "query AllRecipes {\n  recipes {\n    title\n    description\n    preparationDifficulty\n    cook {\n      name\n    }\n  }\n}\n\nquery EasyRecipes {\n  recipes(difficulty: Easy) {\n    title\n    description\n    ingredients\n    cook {\n      name\n    }\n  }\n}\n\nquery SearchByCookName {\n  search(cookName: \"Gordon\") {\n    __typename\n    ... on Recipe {\n      title\n      preparationDifficulty\n      cook {\n        name\n      }\n    }\n    ... on Cook {\n      name\n      yearsOfExperience\n    }\n  }\n}\n"
  },
  {
    "path": "examples/enums-and-unions/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { ExampleResolver } from \"./resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [ExampleResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/enums-and-unions/recipe.data.ts",
    "content": "import { sampleCooks } from \"./cook.data\";\nimport { Difficulty } from \"./difficulty.enum\";\nimport { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    preparationDifficulty: Difficulty.Easy,\n    ingredients: [\"one\", \"two\", \"three\"],\n    cook: sampleCooks[1],\n  }),\n  createRecipe({\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    preparationDifficulty: Difficulty.Easy,\n    ingredients: [\"four\", \"five\", \"six\"],\n    cook: sampleCooks[0],\n  }),\n  createRecipe({\n    title: \"Recipe 3\",\n    preparationDifficulty: Difficulty.Beginner,\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n    cook: sampleCooks[1],\n  }),\n  createRecipe({\n    title: \"Recipe 4\",\n    description: \"Desc 4\",\n    preparationDifficulty: Difficulty.MasterChef,\n    ingredients: [\"ten\", \"eleven\", \"twelve\"],\n    cook: sampleCooks[0],\n  }),\n  createRecipe({\n    title: \"Recipe 5\",\n    preparationDifficulty: Difficulty.Hard,\n    ingredients: [\"thirteen\", \"fourteen\", \"fifteen\"],\n    cook: sampleCooks[0],\n  }),\n];\n"
  },
  {
    "path": "examples/enums-and-unions/recipe.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\nimport { Cook } from \"./cook.type\";\nimport { Difficulty } from \"./difficulty.enum\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n\n  @Field(_type => Difficulty)\n  preparationDifficulty!: Difficulty;\n\n  @Field()\n  cook!: Cook;\n}\n"
  },
  {
    "path": "examples/enums-and-unions/resolver.ts",
    "content": "import { Arg, Query, Resolver } from \"type-graphql\";\nimport { sampleCooks } from \"./cook.data\";\nimport { type Cook } from \"./cook.type\";\nimport { Difficulty } from \"./difficulty.enum\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\nimport { SearchResult } from \"./search-result.union\";\n\n@Resolver()\nexport class ExampleResolver {\n  private recipesData: Recipe[] = sampleRecipes;\n\n  private cooks: Cook[] = sampleCooks;\n\n  @Query(_returns => [Recipe])\n  async recipes(\n    @Arg(\"difficulty\", _type => Difficulty, { nullable: true }) difficulty?: Difficulty,\n  ): Promise<Recipe[]> {\n    if (!difficulty) {\n      return this.recipesData;\n    }\n\n    return this.recipesData.filter(recipe => recipe.preparationDifficulty === difficulty);\n  }\n\n  @Query(_returns => [SearchResult])\n  async search(@Arg(\"cookName\") cookName: string): Promise<Array<typeof SearchResult>> {\n    const recipes = this.recipesData.filter(recipe => recipe.cook.name.match(cookName));\n    const cooks = this.cooks.filter(cook => cook.name.match(cookName));\n\n    return [...recipes, ...cooks];\n  }\n}\n"
  },
  {
    "path": "examples/enums-and-unions/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Cook {\n  name: String!\n  yearsOfExperience: Int!\n}\n\n\"\"\"\nAll possible preparation difficulty levels\n\"\"\"\nenum Difficulty {\n  Beginner\n  Easy\n  Hard\n  MasterChef\n  Medium\n}\n\ntype Query {\n  recipes(difficulty: Difficulty): [Recipe!]!\n  search(cookName: String!): [SearchResult!]!\n}\n\ntype Recipe {\n  cook: Cook!\n  description: String\n  ingredients: [String!]!\n  preparationDifficulty: Difficulty!\n  title: String!\n}\n\nunion SearchResult = Cook | Recipe\n"
  },
  {
    "path": "examples/enums-and-unions/search-result.union.ts",
    "content": "import { createUnionType } from \"type-graphql\";\nimport { Cook } from \"./cook.type\";\nimport { Recipe } from \"./recipe.type\";\n\nexport const SearchResult = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Recipe, Cook] as const,\n});\n"
  },
  {
    "path": "examples/extensions/context.type.ts",
    "content": "import { type User } from \"./user.type\";\n\nexport interface Context {\n  user?: User;\n}\n"
  },
  {
    "path": "examples/extensions/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    title\n    description\n    ingredients\n    averageRating\n    ratings\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(title: \"Sample Recipe\") {\n    averageRating\n  }\n}\n\nmutation DeleteRecipe {\n  deleteRecipe(title: \"Recipe 1\")\n}\n"
  },
  {
    "path": "examples/extensions/helpers/config.extractors.ts",
    "content": "import {\n  type GraphQLFieldConfig,\n  type GraphQLObjectTypeConfig,\n  type GraphQLResolveInfo,\n} from \"graphql\";\n\nexport const extractFieldConfig = (info: GraphQLResolveInfo): GraphQLFieldConfig<any, any> => {\n  const { type, extensions, description, deprecationReason } =\n    info.parentType.getFields()[info.fieldName];\n\n  return {\n    type,\n    description,\n    extensions,\n    deprecationReason,\n  };\n};\n\nexport const extractParentTypeConfig = (\n  info: GraphQLResolveInfo,\n): GraphQLObjectTypeConfig<any, any> => info.parentType.toConfig();\n"
  },
  {
    "path": "examples/extensions/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { Container } from \"typedi\";\nimport { type Context } from \"./context.type\";\nimport { LoggerMiddleware } from \"./logger.middleware\";\nimport { RecipeResolver } from \"./resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // IOC container\n    container: Container,\n    // Global middleware\n    globalMiddlewares: [LoggerMiddleware],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({\n    schema,\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    // Provide context\n    context: async () => ({\n      // Example user\n      user: {\n        id: 123,\n        name: \"Sample user\",\n      },\n    }),\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/extensions/log-message.decorator.ts",
    "content": "import { Extensions } from \"type-graphql\";\n\ninterface LogOptions {\n  message: string;\n  level?: number;\n}\n\nexport function LogMessage(messageOrOptions: string | LogOptions) {\n  // Parse the parameters of the custom decorator\n  const log: LogOptions =\n    typeof messageOrOptions === \"string\"\n      ? {\n          level: 4,\n          message: messageOrOptions,\n        }\n      : messageOrOptions;\n\n  // Return the '@Extensions' decorator with a prepared property\n  return Extensions({ log });\n}\n"
  },
  {
    "path": "examples/extensions/logger.middleware.ts",
    "content": "import {\n  type GraphQLFieldConfig,\n  type GraphQLObjectTypeConfig,\n  type GraphQLResolveInfo,\n} from \"graphql\";\nimport { type MiddlewareInterface, type NextFn, type ResolverData } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { type Context } from \"./context.type\";\nimport { extractFieldConfig, extractParentTypeConfig } from \"./helpers/config.extractors\";\nimport { Logger } from \"./logger.service\";\n\ninterface LoggerConfig {\n  message?: string;\n  level?: number;\n}\n\nconst extractLoggerExtensionsFromConfig = (\n  config: GraphQLObjectTypeConfig<any, any> | GraphQLFieldConfig<any, any>,\n): LoggerConfig => (config.extensions && (config.extensions.log as LoggerConfig)) || {};\n\nconst getLoggerExtensions = (info: GraphQLResolveInfo) => {\n  const fieldConfig = extractFieldConfig(info);\n  const fieldLoggerExtensions = extractLoggerExtensionsFromConfig(fieldConfig);\n\n  const parentConfig = extractParentTypeConfig(info);\n  const parentLoggerExtensions = extractLoggerExtensionsFromConfig(parentConfig);\n\n  return {\n    ...parentLoggerExtensions,\n    ...fieldLoggerExtensions,\n  };\n};\n\n@Service()\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ context: { user }, info }: ResolverData<Context>, next: NextFn) {\n    const { message, level = 0 } = getLoggerExtensions(info);\n\n    if (message) {\n      this.logger.log(level, `${user ? ` (user: ${user.id})` : \"\"}`, message);\n    }\n\n    return next();\n  }\n}\n"
  },
  {
    "path": "examples/extensions/logger.service.ts",
    "content": "import { Service } from \"typedi\";\n\n@Service()\nexport class Logger {\n  log(...args: unknown[]) {\n    console.log(...args);\n  }\n}\n"
  },
  {
    "path": "examples/extensions/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    ingredients: [\"one\", \"two\", \"three\"],\n    ratings: [3, 4, 5, 5, 5],\n  }),\n  createRecipe({\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    ingredients: [\"four\", \"five\", \"six\"],\n    ratings: [3, 4, 5, 3, 2],\n  }),\n  createRecipe({\n    title: \"Recipe 3\",\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n    ratings: [4, 4, 5, 5, 4],\n  }),\n];\n"
  },
  {
    "path": "examples/extensions/recipe.type.ts",
    "content": "import { Extensions, Field, Float, Int, ObjectType } from \"type-graphql\";\nimport { LogMessage } from \"./log-message.decorator\";\n\n@ObjectType()\n// Log a message when any Recipe field is accessed\n@LogMessage(\"Recipe field accessed\")\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  // Use raw 'Extensions' decorator\n  @Extensions({ log: { message: \"Ingredients field accessed\", level: 0 } })\n  ingredients!: string[];\n\n  // Override the object type log message\n  @LogMessage(\"Ratings accessed\")\n  @Field(_type => [Int])\n  ratings!: number[];\n\n  @Field(_type => Float, { nullable: true })\n  get averageRating(): number | null {\n    if (!this.ratings.length) {\n      return null;\n    }\n    return this.ratings.reduce((a, b) => a + b, 0) / this.ratings.length;\n  }\n}\n"
  },
  {
    "path": "examples/extensions/resolver.ts",
    "content": "import { Arg, Mutation, Query, Resolver } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { LogMessage } from \"./log-message.decorator\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\n\n@Service()\n@Resolver()\nexport class RecipeResolver {\n  private recipesData: Recipe[] = sampleRecipes.slice();\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return this.recipesData;\n  }\n\n  @Mutation()\n  addRecipe(\n    @Arg(\"title\") title: string,\n    @Arg(\"description\", { nullable: true }) description?: string,\n  ): Recipe {\n    const newRecipe = Object.assign(new Recipe(), {\n      title,\n      description,\n      ratings: [],\n    });\n    this.recipesData.push(newRecipe);\n    return newRecipe;\n  }\n\n  @LogMessage(\"Recipe deletion requested\")\n  @Mutation()\n  deleteRecipe(@Arg(\"title\") title: string): boolean {\n    const foundRecipeIndex = this.recipesData.findIndex(it => it.title === title);\n    if (!foundRecipeIndex) {\n      return false;\n    }\n    this.recipesData.splice(foundRecipeIndex, 1);\n    return true;\n  }\n}\n"
  },
  {
    "path": "examples/extensions/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(description: String, title: String!): Recipe!\n  deleteRecipe(title: String!): Boolean!\n}\n\ntype Query {\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float\n  description: String\n  ingredients: [String!]!\n  ratings: [Int!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/extensions/user.type.ts",
    "content": "export interface User {\n  id: number;\n  name: string;\n}\n"
  },
  {
    "path": "examples/generic-types/examples.graphql",
    "content": "query GetRecipes {\n  recipes(first: 3) {\n    items {\n      title\n      ratings\n    }\n    total\n    hasMore\n  }\n}\n\nmutation AddRecipe {\n  addSampleRecipe {\n    title\n  }\n}\n"
  },
  {
    "path": "examples/generic-types/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/generic-types/paginated-response.type.ts",
    "content": "import { type ClassType, Field, Int, ObjectType } from \"type-graphql\";\n\nexport function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | string | number | boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(_type => [itemsFieldValue])\n    items!: TItemsFieldValue[];\n\n    @Field(_type => Int)\n    total!: number;\n\n    @Field()\n    hasMore!: boolean;\n  }\n\n  return PaginatedResponseClass;\n}\n"
  },
  {
    "path": "examples/generic-types/recipe.data.ts",
    "content": "import { type Recipe } from \"./recipe.type\";\n\nexport function createSampleRecipes(): Recipe[] {\n  return [\n    {\n      description: \"Desc 1\",\n      title: \"Recipe 1\",\n      ratings: [0, 3, 1],\n    },\n    {\n      description: \"Desc 2\",\n      title: \"Recipe 2\",\n      ratings: [4, 2, 3, 1],\n    },\n    {\n      description: \"Desc 3\",\n      title: \"Recipe 3\",\n      ratings: [5, 4],\n    },\n  ];\n}\n"
  },
  {
    "path": "examples/generic-types/recipe.resolver.ts",
    "content": "/* eslint-disable max-classes-per-file */\nimport { Arg, Int, Mutation, ObjectType, Query, Resolver } from \"type-graphql\";\nimport { PaginatedResponse } from \"./paginated-response.type\";\nimport { createSampleRecipes } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\n\n// Create a temporary class for the abstract generic class 'instance'\n@ObjectType()\nclass RecipesResponse extends PaginatedResponse(Recipe) {\n  // Add more fields here if needed\n}\n\n@Resolver()\nexport class RecipeResolver {\n  private readonly recipes = createSampleRecipes();\n\n  @Query({ name: \"recipes\" })\n  getRecipes(\n    @Arg(\"first\", _type => Int, { nullable: true, defaultValue: 10 }) first: number,\n  ): RecipesResponse {\n    const total = this.recipes.length;\n    return {\n      items: this.recipes.slice(0, first),\n      hasMore: total > first,\n      total,\n    };\n  }\n\n  @Mutation()\n  addSampleRecipe(): Recipe {\n    const recipe: Recipe = {\n      title: \"Sample recipe\",\n      description: \"Sample description\",\n      ratings: [1, 2, 3, 4],\n    };\n    this.recipes.push(recipe);\n    return recipe;\n  }\n}\n"
  },
  {
    "path": "examples/generic-types/recipe.type.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Int])\n  ratings!: number[];\n}\n"
  },
  {
    "path": "examples/generic-types/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addSampleRecipe: Recipe!\n}\n\ntype Query {\n  recipes(first: Int = 10): RecipesResponse!\n}\n\ntype Recipe {\n  description: String\n  ratings: [Int!]!\n  title: String!\n}\n\ntype RecipesResponse {\n  hasMore: Boolean!\n  items: [Recipe!]!\n  total: Int!\n}\n"
  },
  {
    "path": "examples/graphql-scalars/examples.graphql",
    "content": "query GetRecipe1 {\n  recipe(title: \"Recipe 1\") {\n    title\n    description\n    ratings\n    creationDate\n    ratingsCount(minRate: 2)\n    averageRating\n  }\n}\n\nquery GetRecipes {\n  recipes {\n    title\n    description\n    creationDate\n    averageRating\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New recipe\", description: \"Simple description\" }) {\n    creationDate\n  }\n}\n"
  },
  {
    "path": "examples/graphql-scalars/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/graphql-scalars/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>) {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport function createRecipeSamples() {\n  return [\n    createRecipe({\n      description: \"Desc 1\",\n      title: \"Recipe 1\",\n      ratings: [0, 3, 1],\n      creationDate: new Date(\"2018-04-11\"),\n    }),\n    createRecipe({\n      description: \"Desc 2\",\n      title: \"Recipe 2\",\n      ratings: [4, 2, 3, 1],\n      creationDate: new Date(\"2018-04-15\"),\n    }),\n    createRecipe({\n      description: \"Desc 3\",\n      title: \"Recipe 3\",\n      ratings: [5, 4],\n      creationDate: new Date(),\n    }),\n  ];\n}\n"
  },
  {
    "path": "examples/graphql-scalars/recipe.input.ts",
    "content": "import { GraphQLNonEmptyString } from \"graphql-scalars\";\nimport { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field(_type => GraphQLNonEmptyString)\n  title!: string;\n\n  @Field(_type => GraphQLNonEmptyString, { nullable: true })\n  description?: string;\n}\n"
  },
  {
    "path": "examples/graphql-scalars/recipe.resolver.ts",
    "content": "import { GraphQLNonNegativeInt } from \"graphql-scalars\";\nimport {\n  Arg,\n  FieldResolver,\n  Int,\n  Mutation,\n  Query,\n  Resolver,\n  type ResolverInterface,\n  Root,\n} from \"type-graphql\";\nimport { createRecipeSamples } from \"./recipe.data\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver implements ResolverInterface<Recipe> {\n  private readonly items: Recipe[] = createRecipeSamples();\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"title\") title: string): Promise<Recipe | undefined> {\n    return this.items.find(recipe => recipe.title === title);\n  }\n\n  @Query(_returns => [Recipe], { description: \"Get all the recipes from around the world \" })\n  async recipes(): Promise<Recipe[]> {\n    return this.items;\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipeInput: RecipeInput): Promise<Recipe> {\n    const recipe = Object.assign(new Recipe(), {\n      description: recipeInput.description,\n      title: recipeInput.title,\n      ratings: [],\n      creationDate: new Date(),\n    });\n    await this.items.push(recipe);\n\n    return recipe;\n  }\n\n  @FieldResolver(_returns => GraphQLNonNegativeInt)\n  ratingsCount(\n    @Root() recipe: Recipe,\n    @Arg(\"minRate\", _type => Int, { defaultValue: 0 }) minRate: number,\n  ): number {\n    return recipe.ratings.filter(rating => rating >= minRate).length;\n  }\n}\n"
  },
  {
    "path": "examples/graphql-scalars/recipe.type.ts",
    "content": "import {\n  GraphQLNonEmptyString,\n  GraphQLNonNegativeFloat,\n  GraphQLNonNegativeInt,\n  GraphQLTimestamp,\n} from \"graphql-scalars\";\nimport { Field, ObjectType } from \"type-graphql\";\n\n@ObjectType({ description: \"Object representing cooking recipe\" })\nexport class Recipe {\n  @Field(_type => GraphQLNonEmptyString)\n  title!: string;\n\n  @Field(_type => GraphQLNonEmptyString, {\n    nullable: true,\n    deprecationReason: \"Use 'description' field instead\",\n  })\n  get specification(): string | undefined {\n    return this.description;\n  }\n\n  @Field(_type => GraphQLNonEmptyString, {\n    nullable: true,\n    description: \"The recipe description with preparation info\",\n  })\n  description?: string;\n\n  @Field(_type => [GraphQLNonNegativeInt])\n  ratings!: number[];\n\n  @Field(_type => GraphQLTimestamp)\n  creationDate!: Date;\n\n  @Field(_type => GraphQLNonNegativeInt)\n  ratingsCount!: number;\n\n  @Field(_type => GraphQLNonNegativeFloat, { nullable: true })\n  get averageRating(): number | null {\n    const ratingsCount = this.ratings.length;\n    if (ratingsCount === 0) {\n      return null;\n    }\n    const ratingsSum = this.ratings.reduce((a, b) => a + b, 0);\n\n    return ratingsSum / ratingsCount;\n  }\n}\n"
  },
  {
    "path": "examples/graphql-scalars/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n}\n\n\"\"\"\nA string that cannot be passed as an empty value\n\"\"\"\nscalar NonEmptyString\n\n\"\"\"\nFloats that will have a value of 0 or more.\n\"\"\"\nscalar NonNegativeFloat\n\n\"\"\"\nIntegers that will have a value of 0 or more.\n\"\"\"\nscalar NonNegativeInt\n\ntype Query {\n  recipe(title: String!): Recipe\n\n  \"\"\"\n  Get all the recipes from around the world\n  \"\"\"\n  recipes: [Recipe!]!\n}\n\n\"\"\"\nObject representing cooking recipe\n\"\"\"\ntype Recipe {\n  averageRating: NonNegativeFloat\n  creationDate: Timestamp!\n\n  \"\"\"\n  The recipe description with preparation info\n  \"\"\"\n  description: NonEmptyString\n  ratings: [NonNegativeInt!]!\n  ratingsCount(minRate: Int! = 0): NonNegativeInt!\n  specification: NonEmptyString @deprecated(reason: \"Use 'description' field instead\")\n  title: NonEmptyString!\n}\n\ninput RecipeInput {\n  description: NonEmptyString\n  title: NonEmptyString!\n}\n\n\"\"\"\nThe javascript `Date` as integer. Type represents date and time as number of milliseconds from start of UNIX epoch.\n\"\"\"\nscalar Timestamp\n"
  },
  {
    "path": "examples/interfaces-inheritance/employee/employee.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { PersonInput } from \"../person\";\n\n@InputType()\nexport class EmployeeInput extends PersonInput {\n  @Field()\n  companyName!: string;\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/employee/employee.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\nimport { Person } from \"../person\";\n\n@ObjectType()\nexport class Employee extends Person {\n  @Field()\n  companyName!: string;\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/employee/index.ts",
    "content": "export * from \"./employee.input\";\nexport * from \"./employee.type\";\n"
  },
  {
    "path": "examples/interfaces-inheritance/examples.graphql",
    "content": "query GetPersons {\n  persons {\n    __typename\n    id\n    name\n    age\n    ... on Student {\n      universityName\n    }\n    ... on Employee {\n      companyName\n    }\n  }\n}\n\nmutation AddStudent {\n  addStudent(\n    input: { name: \"Student 1\", dateOfBirth: \"1991-11-30T00:00:00.000Z\", universityName: \"Uni 1\" }\n  ) {\n    id\n    age\n  }\n}\n\nmutation AddEmployee {\n  addEmployee(\n    input: { name: \"Employee 1\", dateOfBirth: \"1995-07-23T00:00:00.000Z\", companyName: \"Company 1\" }\n  ) {\n    id\n    age\n  }\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/helpers.ts",
    "content": "import crypto from \"node:crypto\";\n\nexport function getId(): string {\n  const randomNumber = Math.random();\n  const hash = crypto.createHash(\"sha256\");\n  hash.update(randomNumber.toString());\n  return hash.digest(\"hex\");\n}\n\nexport function calculateAge(birthday: Date) {\n  const ageDiffMs = Date.now() - birthday.getTime();\n  const ageDate = new Date(ageDiffMs); // Milliseconds from epoch\n  return Math.abs(ageDate.getUTCFullYear() - 1970);\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { Person } from \"./person\";\nimport { MultiResolver } from \"./resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [MultiResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Provide the type that implements an interface but it is not directly used in schema\n    orphanedTypes: [Person],\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/interfaces-inheritance/person/index.ts",
    "content": "export * from \"./person.input\";\nexport * from \"./person.interface\";\nexport * from \"./person.type\";\n"
  },
  {
    "path": "examples/interfaces-inheritance/person/person.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\n\n@InputType()\nexport class PersonInput {\n  @Field()\n  name!: string;\n\n  @Field()\n  dateOfBirth!: Date;\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/person/person.interface.ts",
    "content": "import { Arg, Field, ID, Int, InterfaceType } from \"type-graphql\";\nimport { type IResource } from \"../resource\";\n\n@InterfaceType({\n  // Workaround issue #373 (https://github.com/MichalLytek/type-graphql/issues/373)\n  resolveType: value => value.constructor.name,\n})\nexport abstract class IPerson implements IResource {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  name!: string;\n\n  @Field(_type => Int)\n  age!: number;\n\n  @Field()\n  avatar(@Arg(\"size\") _size: number): string {\n    throw new Error(\"Method not implemented.\");\n  }\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/person/person.type.ts",
    "content": "import { Arg, Field, ObjectType } from \"type-graphql\";\nimport { IPerson } from \"./person.interface\";\n\n@ObjectType({ implements: IPerson })\nexport class Person implements IPerson {\n  id!: string;\n\n  name!: string;\n\n  age!: number;\n\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/resolver.ts",
    "content": "import { Arg, Mutation, Query, Resolver } from \"type-graphql\";\nimport { Employee, EmployeeInput } from \"./employee\";\nimport { calculateAge, getId } from \"./helpers\";\nimport { IPerson } from \"./person\";\nimport { Student, StudentInput } from \"./student\";\n\n@Resolver()\nexport class MultiResolver {\n  private readonly personsRegistry: IPerson[] = [];\n\n  @Query(_returns => [IPerson])\n  persons(): IPerson[] {\n    // This one returns interfaces,\n    // GraphQL has to be able to resolve type of the item\n    return this.personsRegistry;\n  }\n\n  @Mutation()\n  addStudent(@Arg(\"input\") input: StudentInput): Student {\n    // Be sure to create real instances of classes\n    const student = Object.assign(new Student(), {\n      id: getId(),\n      name: input.name,\n      universityName: input.universityName,\n      age: calculateAge(input.dateOfBirth),\n    });\n    this.personsRegistry.push(student);\n    return student;\n  }\n\n  @Mutation()\n  addEmployee(@Arg(\"input\") input: EmployeeInput): Employee {\n    const employee = Object.assign(new Employee(), {\n      id: getId(),\n      name: input.name,\n      companyName: input.companyName,\n      age: calculateAge(input.dateOfBirth),\n    });\n    this.personsRegistry.push(employee);\n    return employee;\n  }\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/resource/index.ts",
    "content": "export * from \"./resource.interface\";\n"
  },
  {
    "path": "examples/interfaces-inheritance/resource/resource.interface.ts",
    "content": "import { Field, ID, InterfaceType } from \"type-graphql\";\n\n@InterfaceType()\nexport abstract class IResource {\n  @Field(_type => ID)\n  id!: string;\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Employee implements IPerson {\n  age: Int!\n  avatar(size: Float!): String!\n  companyName: String!\n  id: ID!\n  name: String!\n}\n\ninput EmployeeInput {\n  companyName: String!\n  dateOfBirth: DateTimeISO!\n  name: String!\n}\n\ninterface IPerson {\n  age: Int!\n  avatar(size: Float!): String!\n  id: ID!\n  name: String!\n}\n\ntype Mutation {\n  addEmployee(input: EmployeeInput!): Employee!\n  addStudent(input: StudentInput!): Student!\n}\n\ntype Person implements IPerson {\n  age: Int!\n  avatar(size: Float!): String!\n  id: ID!\n  name: String!\n}\n\ntype Query {\n  persons: [IPerson!]!\n}\n\ntype Student implements IPerson {\n  age: Int!\n  avatar(size: Float!): String!\n  id: ID!\n  name: String!\n  universityName: String!\n}\n\ninput StudentInput {\n  dateOfBirth: DateTimeISO!\n  name: String!\n  universityName: String!\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/student/index.ts",
    "content": "export * from \"./student.input\";\nexport * from \"./student.type\";\n"
  },
  {
    "path": "examples/interfaces-inheritance/student/student.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { PersonInput } from \"../person\";\n\n@InputType()\nexport class StudentInput extends PersonInput {\n  @Field()\n  universityName!: string;\n}\n"
  },
  {
    "path": "examples/interfaces-inheritance/student/student.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\nimport { Person } from \"../person\";\n\n@ObjectType()\nexport class Student extends Person {\n  @Field()\n  universityName!: string;\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/context.type.ts",
    "content": "import { type User } from \"./user.type\";\n\nexport interface Context {\n  currentUser: User;\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/decorators/current-user.ts",
    "content": "import { createParameterDecorator } from \"type-graphql\";\nimport { type Context } from \"../context.type\";\n\nexport function CurrentUser() {\n  return createParameterDecorator<Context>(({ context }) => context.currentUser);\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/decorators/index.ts",
    "content": "export * from \"./current-user\";\nexport * from \"./validate-args\";\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/decorators/random-id-arg.ts",
    "content": "import { Int, createParameterDecorator } from \"type-graphql\";\n\nconst MAX_ID_VALUE = 3; // Number.MAX_SAFE_INTEGER\n\nexport function RandomIdArg(argName = \"id\") {\n  return createParameterDecorator(\n    ({ args }) => args[argName] ?? Math.round(Math.random() * MAX_ID_VALUE),\n    {\n      arg: {\n        name: argName,\n        typeFunc: () => Int,\n        options: {\n          nullable: true,\n          description: \"Accepts provided id or generates a random one.\",\n          validateFn: (value: number): void => {\n            if (value < 0 || value > MAX_ID_VALUE) {\n              throw new Error(`Invalid value for ${argName}`);\n            }\n          },\n        },\n      },\n    },\n  );\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/decorators/validate-args.ts",
    "content": "import { validate } from \"class-validator\";\nimport {\n  ArgumentValidationError,\n  type ClassType,\n  createMethodMiddlewareDecorator,\n} from \"type-graphql\";\n\n// Sample implementation of custom validation decorator\n// This example use 'class-validator' however you can plug-in 'joi' or any other validation library\nexport function ValidateArgs<T extends object>(Type: ClassType<T>) {\n  return createMethodMiddlewareDecorator(async ({ args }, next) => {\n    const instance = Object.assign(new Type(), args);\n    const validationErrors = await validate(instance);\n    if (validationErrors.length > 0) {\n      throw new ArgumentValidationError(validationErrors);\n    }\n    return next();\n  });\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/examples.graphql",
    "content": "query InvalidArgs {\n  recipes(take: -1) {\n    title\n    description\n  }\n}\n\nquery LoggingQuery {\n  recipes {\n    title\n    description\n    ratings\n  }\n}\n\nquery InterceptorsQuery {\n  recipes(skip: 1, take: 2) {\n    title\n    ratings\n    averageRating\n  }\n}\n\nquery RandomIdQuery {\n  recipe {\n    id\n    title\n    averageRating\n    description\n  }\n}\n\nquery SelectedIdQuery {\n  recipe(id: 2) {\n    id\n    title\n    averageRating\n    description\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport Container from \"typedi\";\nimport { type Context } from \"./context.type\";\nimport { ErrorLoggerMiddleware } from \"./middlewares\";\nimport { RecipeResolver } from \"./recipe\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Array of global middlewares\n    globalMiddlewares: [ErrorLoggerMiddleware],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Registry 3rd party IOC container\n    container: Container,\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    // Provide context for each request\n    context: async (): Promise<Context> => ({\n      // Create mocked user in context\n      currentUser: {\n        id: 123,\n        name: \"Sample user\",\n      },\n    }),\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/logger.ts",
    "content": "import { Service } from \"typedi\";\n\n@Service()\nexport class Logger {\n  log(...args: any[]) {\n    // Replace with a more sophisticated solution\n    console.log(...args);\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/middlewares/error-logger.ts",
    "content": "import {\n  ArgumentValidationError,\n  type MiddlewareInterface,\n  type NextFn,\n  type ResolverData,\n} from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { type Context } from \"../context.type\";\nimport { Logger } from \"../logger\";\n\n@Service()\nexport class ErrorLoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<Context>, next: NextFn) {\n    try {\n      return await next();\n    } catch (err) {\n      this.logger.log({\n        message: (err as Error).message,\n        operation: info.operation.operation,\n        fieldName: info.fieldName,\n        userName: context.currentUser.name,\n      });\n      if (!(err instanceof ArgumentValidationError)) {\n        // Hide errors from db like printing sql query\n        throw new Error(\"Unknown error occurred. Try again later!\");\n      }\n      throw err;\n    }\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/middlewares/index.ts",
    "content": "export * from \"./error-logger\";\nexport * from \"./log-access\";\nexport * from \"./number-interceptor\";\nexport * from \"./resolve-time\";\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/middlewares/log-access.ts",
    "content": "import { type MiddlewareInterface, type NextFn, type ResolverData } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { type Context } from \"../context.type\";\nimport { Logger } from \"../logger\";\n\n@Service()\nexport class LogAccessMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<Context>, next: NextFn) {\n    this.logger.log(\n      `Logging access: ${context.currentUser.name} -> ${info.parentType.name}.${info.fieldName}`,\n    );\n    return next();\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/middlewares/number-interceptor.ts",
    "content": "import { type MiddlewareFn } from \"type-graphql\";\n\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide ratings below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/middlewares/resolve-time.ts",
    "content": "import { type MiddlewareFn } from \"type-graphql\";\n\nexport const ResolveTimeMiddleware: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/recipe/index.ts",
    "content": "export * from \"./recipe.args\";\nexport * from \"./recipe.resolver\";\nexport * from \"./recipe.data\";\nexport * from \"./recipe.type\";\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/recipe/recipe.args.ts",
    "content": "import { Max, Min } from \"class-validator\";\nimport { ArgsType, Field, Int } from \"type-graphql\";\n\n@ArgsType()\nexport class RecipesArgs {\n  @Field(_type => Int)\n  @Min(0)\n  skip = 0;\n\n  @Field(_type => Int)\n  @Min(1)\n  @Max(50)\n  take = 10;\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/recipe/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nlet lastRecipeId = 0;\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), {\n    // eslint-disable-next-line no-plusplus\n    id: lastRecipeId++,\n    ...recipeData,\n  });\n}\n\nexport const recipes = [\n  createRecipe({\n    description: \"Desc 1\",\n    title: \"Recipe 1\",\n    ratings: [0, 3, 1],\n  }),\n  createRecipe({\n    description: \"Desc 2\",\n    title: \"Recipe 2\",\n    ratings: [4, 2, 3, 1],\n  }),\n  createRecipe({\n    description: \"Desc 3\",\n    title: \"Recipe 3\",\n    ratings: [4, 5, 3, 1, 5],\n  }),\n];\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/recipe/recipe.resolver.ts",
    "content": "import { Args, Query, Resolver, UseMiddleware } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { RecipesArgs } from \"./recipe.args\";\nimport { recipes as recipesData } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\nimport { CurrentUser, ValidateArgs } from \"../decorators\";\nimport { RandomIdArg } from \"../decorators/random-id-arg\";\nimport { ResolveTimeMiddleware } from \"../middlewares\";\nimport { User } from \"../user.type\";\n\n@Service()\n@UseMiddleware(ResolveTimeMiddleware)\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  private readonly items: Recipe[] = recipesData;\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@RandomIdArg(\"id\") id: number) {\n    console.log(`Queried for recipe with id: ${id}`);\n    return this.items.find(item => item.id === id);\n  }\n\n  @Query(_returns => [Recipe])\n  @ValidateArgs(RecipesArgs)\n  async recipes(\n    @Args({ validate: false }) // Disable built-in validation here\n    options: RecipesArgs,\n    @CurrentUser() currentUser: User,\n  ): Promise<Recipe[]> {\n    console.log(`User \"${currentUser.name}\" queried for recipes!`);\n    const start = options.skip;\n    const end = options.skip + options.take;\n    return this.items.slice(start, end);\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/recipe/recipe.type.ts",
    "content": "import { Field, Float, Int, ObjectType, UseMiddleware } from \"type-graphql\";\nimport { LogAccessMiddleware, NumberInterceptor } from \"../middlewares\";\n\n@ObjectType()\nexport class Recipe {\n  @Field(_type => Int)\n  id!: number;\n\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Int])\n  @UseMiddleware(LogAccessMiddleware)\n  ratings!: number[];\n\n  @Field(_type => Float, { nullable: true })\n  @UseMiddleware(NumberInterceptor(3))\n  get averageRating(): number | null {\n    const ratingsCount = this.ratings.length;\n    if (ratingsCount === 0) {\n      return null;\n    }\n    const ratingsSum = this.ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratingsCount;\n  }\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Query {\n  recipe(\n    \"\"\"\n    Accepts provided id or generates a random one.\n    \"\"\"\n    id: Int\n  ): Recipe\n  recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float\n  description: String\n  id: Int!\n  ratings: [Int!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/middlewares-custom-decorators/user.type.ts",
    "content": "export interface User {\n  id: number;\n  name: string;\n}\n"
  },
  {
    "path": "examples/mikro-orm/context.type.ts",
    "content": "import { type EntityManager } from \"@mikro-orm/core\";\nimport { type User } from \"./entities\";\n\nexport interface Context {\n  entityManager: EntityManager;\n  user: User;\n}\n"
  },
  {
    "path": "examples/mikro-orm/entities/index.ts",
    "content": "export * from \"./rating\";\nexport * from \"./recipe\";\nexport * from \"./user\";\n"
  },
  {
    "path": "examples/mikro-orm/entities/rating.ts",
    "content": "import { Entity, ManyToOne, OptionalProps, PrimaryKey, Property } from \"@mikro-orm/core\";\nimport { Field, Int, ObjectType } from \"type-graphql\";\nimport { Recipe } from \"./recipe\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Rating {\n  @PrimaryKey()\n  readonly id!: number;\n\n  @Field(_type => Int)\n  @Property({ type: \"smallint\" })\n  value!: number;\n\n  @Field(_type => User)\n  @ManyToOne(_type => User)\n  user!: User;\n\n  @Field()\n  @Property({ onCreate: () => new Date() })\n  date!: Date;\n\n  @ManyToOne(_type => Recipe)\n  recipe!: Recipe;\n\n  [OptionalProps]?: \"date\";\n}\n"
  },
  {
    "path": "examples/mikro-orm/entities/recipe.ts",
    "content": "import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from \"@mikro-orm/core\";\nimport { Field, ID, ObjectType } from \"type-graphql\";\nimport { Rating } from \"./rating\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  @PrimaryKey()\n  readonly id!: number;\n\n  @Field()\n  @Property()\n  title!: string;\n\n  @Field({ nullable: true })\n  @Property({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Rating])\n  @OneToMany(_type => Rating, rating => rating.recipe)\n  ratings = new Collection<Rating>(this);\n\n  @Field(_type => User)\n  @ManyToOne(_type => User)\n  author!: User;\n}\n"
  },
  {
    "path": "examples/mikro-orm/entities/user.ts",
    "content": "import { Entity, PrimaryKey, Property } from \"@mikro-orm/core\";\nimport { Field, ID, ObjectType } from \"type-graphql\";\n\n@ObjectType()\n@Entity()\nexport class User {\n  @Field(_type => ID)\n  @PrimaryKey()\n  readonly id!: number;\n\n  @Field()\n  @Property()\n  email!: string;\n\n  @Field({ nullable: true })\n  @Property({ nullable: true })\n  nickname?: string;\n\n  @Property()\n  password!: string;\n}\n"
  },
  {
    "path": "examples/mikro-orm/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    id\n    title\n    author {\n      email\n    }\n    ratings {\n      value\n    }\n  }\n}\n\nquery GetRecipe {\n  recipe(recipeId: 1) {\n    id\n    title\n    ratings {\n      value\n      user {\n        nickname\n      }\n      date\n    }\n    author {\n      id\n      nickname\n      email\n    }\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New Recipe\" }) {\n    id\n    ratings {\n      value\n    }\n    author {\n      nickname\n    }\n  }\n}\n\nmutation RatingRecipe {\n  rating(rating: { recipeId: 3, value: 4 }) {\n    id\n    ratings {\n      value\n      user {\n        email\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "examples/mikro-orm/helpers.ts",
    "content": "import { type EntityManager } from \"@mikro-orm/core\";\nimport { Rating, Recipe, User } from \"./entities\";\n\nexport async function seedDatabase(em: EntityManager) {\n  const defaultUser = em.create(User, {\n    email: \"admin@github.com\",\n    nickname: \"administrator\",\n    password: \"s3cr3tp4ssw0rd\",\n  });\n  em.persist(defaultUser);\n\n  const recipe1 = em.create(Recipe, {\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    author: defaultUser,\n  });\n  recipe1.ratings.add(\n    em.create(Rating, { value: 2, user: defaultUser, recipe: recipe1 }),\n    em.create(Rating, { value: 4, user: defaultUser, recipe: recipe1 }),\n    em.create(Rating, { value: 5, user: defaultUser, recipe: recipe1 }),\n    em.create(Rating, { value: 3, user: defaultUser, recipe: recipe1 }),\n    em.create(Rating, { value: 4, user: defaultUser, recipe: recipe1 }),\n  );\n  em.persist(recipe1);\n\n  const recipe2 = em.create(Recipe, {\n    title: \"Recipe 2\",\n    author: defaultUser,\n  });\n  recipe2.ratings.add(\n    em.create(Rating, { value: 2, user: defaultUser, recipe: recipe2 }),\n    em.create(Rating, { value: 4, user: defaultUser, recipe: recipe2 }),\n  );\n  em.persist(recipe2);\n\n  await em.flush();\n  return { defaultUser };\n}\n"
  },
  {
    "path": "examples/mikro-orm/index.ts",
    "content": "import \"reflect-metadata\";\nimport \"dotenv/config\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { MikroORM, ReflectMetadataProvider } from \"@mikro-orm/core\";\nimport { PostgreSqlDriver } from \"@mikro-orm/postgresql\";\nimport { buildSchema } from \"type-graphql\";\nimport { type Context } from \"./context.type\";\nimport { Rating, Recipe, User } from \"./entities\";\nimport { seedDatabase } from \"./helpers\";\nimport { RatingResolver, RecipeResolver } from \"./resolvers\";\n\nasync function bootstrap() {\n  // Initialize MikroORM\n  const orm = await MikroORM.init<PostgreSqlDriver>({\n    driver: PostgreSqlDriver,\n    clientUrl: process.env.DATABASE_URL,\n    entities: [Rating, Recipe, User],\n    metadataProvider: ReflectMetadataProvider,\n    metadataCache: { enabled: false },\n  });\n  const generator = orm.getSchemaGenerator();\n  await generator.dropSchema();\n  await generator.createSchema();\n  await generator.updateSchema();\n\n  // Seed database with some data\n  const { defaultUser } = await seedDatabase(orm.em.fork());\n\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver, RatingResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    validate: false,\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({\n    schema,\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    context: async () =>\n      ({\n        user: defaultUser,\n        // Create fresh instance of entity manager per request\n        entityManager: orm.em.fork(),\n      }) satisfies Context,\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/index.ts",
    "content": "export * from \"./rating.resolver\";\nexport * from \"./recipe.resolver\";\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/rating.resolver.ts",
    "content": "import { Ctx, FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Context } from \"../context.type\";\nimport { Rating, User } from \"../entities\";\n\n@Resolver(_of => Rating)\nexport class RatingResolver {\n  @FieldResolver()\n  async user(@Root() rating: Rating, @Ctx() { entityManager }: Context): Promise<User> {\n    return entityManager.findOneOrFail(User, rating.user.id);\n  }\n}\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/recipe.resolver.ts",
    "content": "import { Arg, Ctx, FieldResolver, Int, Mutation, Query, Resolver, Root } from \"type-graphql\";\nimport { RatingInput, RecipeInput } from \"./types\";\nimport { Context } from \"../context.type\";\nimport { Rating, Recipe, User } from \"../entities\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  @Query(_returns => Recipe, { nullable: true })\n  recipe(@Arg(\"recipeId\", _type => Int) recipeId: number, @Ctx() { entityManager }: Context) {\n    return entityManager.findOne(Recipe, recipeId);\n  }\n\n  @Query(_returns => [Recipe])\n  recipes(@Ctx() { entityManager }: Context): Promise<Recipe[]> {\n    return entityManager.find(Recipe, {});\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(\n    @Arg(\"recipe\") recipeInput: RecipeInput,\n    @Ctx() { user, entityManager }: Context,\n  ): Promise<Recipe> {\n    const recipe = entityManager.create(Recipe, {\n      title: recipeInput.title,\n      description: recipeInput.description,\n      author: entityManager.getReference(User, user.id),\n    });\n    await entityManager.persistAndFlush(recipe);\n    return recipe;\n  }\n\n  @Mutation(_returns => Recipe)\n  async rate(\n    @Arg(\"rate\") rateInput: RatingInput,\n    @Ctx() { user, entityManager }: Context,\n  ): Promise<Recipe> {\n    // Find the recipe\n    const recipe = await entityManager.findOne(Recipe, rateInput.recipeId, {\n      populate: [\"ratings\"],\n    });\n    if (!recipe) {\n      throw new Error(\"Invalid recipe ID\");\n    }\n\n    // Set the new recipe rating\n    const newRating = entityManager.create(Rating, {\n      recipe,\n      value: rateInput.value,\n      user: entityManager.getReference(User, user.id),\n    });\n    recipe.ratings.add(newRating);\n\n    // Update the recipe\n    await entityManager.persistAndFlush(recipe);\n\n    return recipe;\n  }\n\n  @FieldResolver()\n  ratings(@Root() recipe: Recipe, @Ctx() { entityManager }: Context) {\n    return entityManager.find(Rating, { recipe: { id: recipe.id } });\n  }\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe, @Ctx() { entityManager }: Context): Promise<User> {\n    return entityManager.findOneOrFail(User, recipe.author.id);\n  }\n}\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/types/index.ts",
    "content": "export * from \"./rating.input\";\nexport * from \"./recipe.input\";\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/types/rating.input.ts",
    "content": "import { Field, InputType, Int } from \"type-graphql\";\n\n@InputType()\nexport class RatingInput {\n  @Field(_type => Int)\n  recipeId!: number;\n\n  @Field(_type => Int)\n  value!: number;\n}\n"
  },
  {
    "path": "examples/mikro-orm/resolvers/types/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"../../entities\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n"
  },
  {
    "path": "examples/mikro-orm/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n  rate(rate: RatingInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: Int!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Rating {\n  date: DateTimeISO!\n  user: User!\n  value: Int!\n}\n\ninput RatingInput {\n  recipeId: Int!\n  value: Int!\n}\n\ntype Recipe {\n  author: User!\n  description: String\n  id: ID!\n  ratings: [Rating!]!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n\ntype User {\n  email: String!\n  id: ID!\n  nickname: String\n}\n"
  },
  {
    "path": "examples/mixin-classes/examples.graphql",
    "content": "query GetUsers {\n  users {\n    ...UserInfo\n  }\n}\n\nmutation CreateUser {\n  createUser(\n    input: {\n      forename: \"Sample 1\"\n      dateOfBirth: \"2000-09-21T14:54:17.369Z\"\n      email: \"test@test.test\"\n      password: \"qwerty123\"\n    }\n  ) {\n    ...UserInfo\n  }\n}\nmutation AmendUser {\n  amendUser(\n    input: {\n      id: 1\n      forename: \"Sample Amend 1\"\n      dateOfBirth: \"2000-09-21T14:54:17.369Z\"\n      email: \"test2@test.test\"\n    }\n  ) {\n    ...UserInfo\n  }\n}\n\nfragment UserInfo on User {\n  id\n  forename\n  surname\n  dateOfBirth\n  email\n}\n"
  },
  {
    "path": "examples/mixin-classes/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { UserResolver } from \"./resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [UserResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    skipCheck: true,\n    validate: true,\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/mixin-classes/inputs/amend.user.input.ts",
    "content": "import { InputType } from \"type-graphql\";\nimport { withId } from \"../mixins\";\nimport { UserDetails } from \"../types\";\n\n// 'AmendUser' is like the full 'User' class without the password\n@InputType()\nexport class AmendUserInput extends withId(UserDetails) {}\n"
  },
  {
    "path": "examples/mixin-classes/inputs/create.user.input.ts",
    "content": "import { InputType } from \"type-graphql\";\nimport { withPassword } from \"../mixins\";\nimport { UserDetails } from \"../types\";\n\n// 'CreateUser' is like the full 'User' class without the id\n@InputType()\nexport class CreateUserInput extends withPassword(UserDetails) {}\n"
  },
  {
    "path": "examples/mixin-classes/inputs/index.ts",
    "content": "export * from \"./amend.user.input\";\nexport * from \"./create.user.input\";\n"
  },
  {
    "path": "examples/mixin-classes/mixins/index.ts",
    "content": "export * from \"./with.id\";\nexport * from \"./with.password\";\n"
  },
  {
    "path": "examples/mixin-classes/mixins/with.id.ts",
    "content": "import { type ClassType, Field, InputType, Int, ObjectType } from \"type-graphql\";\n\n// Adds 'id' property to the base, extended class\nexport function withId<TClassType extends ClassType>(BaseClass: TClassType) {\n  @ObjectType()\n  @InputType()\n  class IDTrait extends BaseClass {\n    @Field(_type => Int)\n    id!: number;\n  }\n\n  return IDTrait;\n}\n"
  },
  {
    "path": "examples/mixin-classes/mixins/with.password.ts",
    "content": "import { MinLength } from \"class-validator\";\nimport { type ClassType, Field, InputType, ObjectType } from \"type-graphql\";\n\n// Adds 'password' property with validation to the base, extended class\nexport function withPassword<TClassType extends ClassType>(BaseClass: TClassType) {\n  @ObjectType()\n  @InputType()\n  class PasswordTrait extends BaseClass {\n    @MinLength(8)\n    @Field()\n    password!: string;\n  }\n\n  return PasswordTrait;\n}\n"
  },
  {
    "path": "examples/mixin-classes/resolver.ts",
    "content": "import { Arg, Mutation, Query, Resolver } from \"type-graphql\";\nimport { AmendUserInput, CreateUserInput } from \"./inputs\";\nimport { User } from \"./types\";\n\n@Resolver()\nexport class UserResolver {\n  private autoIncrementId = 0;\n\n  private readonly usersData: User[] = [];\n\n  @Query(_returns => [User])\n  async users(): Promise<User[]> {\n    return this.usersData;\n  }\n\n  @Mutation(_returns => User)\n  async createUser(@Arg(\"input\") userData: CreateUserInput): Promise<User> {\n    // Generate the ID and store the password\n    this.autoIncrementId += 1;\n    const user: User = { ...userData, id: this.autoIncrementId };\n    this.usersData.push(user);\n    return user;\n  }\n\n  @Mutation(_returns => User)\n  async amendUser(@Arg(\"input\") { id, ...userData }: AmendUserInput): Promise<User> {\n    // Receive the ID but can't change the password\n    const user = this.usersData.find(it => it.id === id);\n    if (!user) {\n      throw new Error(`Invalid ID: ${id}`);\n    }\n    Object.assign(user, userData);\n    return user;\n  }\n}\n"
  },
  {
    "path": "examples/mixin-classes/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ninput AmendUserInput {\n  dateOfBirth: DateTimeISO!\n  email: String!\n  forename: String!\n  id: Int!\n  surname: String\n}\n\ninput CreateUserInput {\n  dateOfBirth: DateTimeISO!\n  email: String!\n  forename: String!\n  password: String!\n  surname: String\n}\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  amendUser(input: AmendUserInput!): User!\n  createUser(input: CreateUserInput!): User!\n}\n\ntype Query {\n  users: [User!]!\n}\n\ntype User {\n  dateOfBirth: DateTimeISO!\n  email: String!\n  forename: String!\n  id: Int!\n  surname: String\n}\n"
  },
  {
    "path": "examples/mixin-classes/types/index.ts",
    "content": "export * from \"./user\";\nexport * from \"./user.details\";\n"
  },
  {
    "path": "examples/mixin-classes/types/user.details.ts",
    "content": "import { IsEmail } from \"class-validator\";\nimport { Field, InputType, ObjectType } from \"type-graphql\";\n\n// 'UserDetails' stores base common user properties\n@ObjectType()\n@InputType(\"UserDetailsInput\")\nexport class UserDetails {\n  @Field()\n  forename!: string;\n\n  @Field({ nullable: true })\n  surname?: string;\n\n  @Field(_type => Date)\n  dateOfBirth!: Date;\n\n  @IsEmail()\n  @Field()\n  email!: string;\n}\n"
  },
  {
    "path": "examples/mixin-classes/types/user.ts",
    "content": "import { ObjectType } from \"type-graphql\";\nimport { UserDetails } from \"./user.details\";\nimport { withId } from \"../mixins/with.id\";\n\n// 'User' is a full object with 'id' and hidden 'password'\n@ObjectType()\nexport class User extends withId(UserDetails) {\n  // No TypeGraphQL decorator, hidden in schema\n  password!: string;\n}\n"
  },
  {
    "path": "examples/query-complexity/examples.graphql",
    "content": "query GetRecipesWithComplexityError {\n  recipes(count: 3) {\n    title\n    averageRating\n  }\n}\n\nquery GetRecipesWithoutComplexityError {\n  recipes(count: 2) {\n    title\n    ratingsCount\n  }\n}\n"
  },
  {
    "path": "examples/query-complexity/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { fieldExtensionsEstimator, getComplexity, simpleEstimator } from \"graphql-query-complexity\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\n// Maximum allowed complexity\nconst MAX_COMPLEXITY = 20;\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/query-complexity/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport function createRecipeSamples() {\n  return [\n    createRecipe({\n      title: \"Recipe 1\",\n      ratings: [0, 3, 1],\n    }),\n    createRecipe({\n      title: \"Recipe 2\",\n      ratings: [4, 2, 3, 1],\n    }),\n    createRecipe({\n      title: \"Recipe 3\",\n      ratings: [5, 4],\n    }),\n  ];\n}\n"
  },
  {
    "path": "examples/query-complexity/recipe.resolver.ts",
    "content": "import { Arg, FieldResolver, Query, Resolver, type ResolverInterface, Root } from \"type-graphql\";\nimport { createRecipeSamples } from \"./recipe.data\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver implements ResolverInterface<Recipe> {\n  private readonly items: Recipe[] = createRecipeSamples();\n\n  @Query(_returns => [Recipe], {\n    /*\n      Pass also a calculation function in the complexity option\n      to determine a custom complexity. This function provide the\n      complexity of the child nodes as well as the field input arguments.\n      That way a more realistic estimation of individual field\n      complexity values is made, e.g. by multiplying childComplexity by the number of items in array\n    */\n    complexity: ({ childComplexity, args }) => args.count * childComplexity,\n  })\n  async recipes(@Arg(\"count\") count: number): Promise<Recipe[]> {\n    return this.items.slice(0, count);\n  }\n\n  /* Complexity in field resolver overrides complexity of equivalent field type */\n  @FieldResolver({ complexity: 5 })\n  ratingsCount(@Root() recipe: Recipe): number {\n    return recipe.ratings.length;\n  }\n}\n"
  },
  {
    "path": "examples/query-complexity/recipe.type.ts",
    "content": "import { Field, Float, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  /* By default, every field gets a complexity of 1 */\n  @Field()\n  title!: string;\n\n  /* Which can be customized by passing the complexity parameter */\n  @Field(_type => Int, { complexity: 2 })\n  ratingsCount!: number;\n\n  @Field(_type => Float, {\n    nullable: true,\n    complexity: 10,\n  })\n  get averageRating(): number | null {\n    const ratingsCount = this.ratings.length;\n    if (ratingsCount === 0) {\n      return null;\n    }\n    const ratingsSum = this.ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratingsCount;\n  }\n\n  // Internal property, not exposed in schema\n  ratings!: number[];\n}\n"
  },
  {
    "path": "examples/query-complexity/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Query {\n  recipes(count: Float!): [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float\n  ratingsCount: Int!\n  title: String!\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/comment.input.ts",
    "content": "import { Field, ID, InputType } from \"type-graphql\";\nimport { type Comment } from \"./comment.type\";\n\n@InputType()\nexport class CommentInput implements Partial<Comment> {\n  @Field(_type => ID)\n  recipeId!: string;\n\n  @Field({ nullable: true })\n  nickname?: string;\n\n  @Field()\n  content!: string;\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/comment.type.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Comment {\n  @Field({ nullable: true })\n  nickname?: string;\n\n  @Field()\n  content!: string;\n\n  @Field()\n  date!: Date;\n}\n\nexport interface NewCommentPayload {\n  recipeId: string;\n\n  dateString: string; // Limitation of Redis payload serialization\n\n  content: string;\n\n  nickname?: string;\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/examples.graphql",
    "content": "query FirstRecipe {\n  recipe(id: \"1\") {\n    title\n    description\n    comments {\n      nickname\n      content\n      date\n    }\n  }\n}\n\nmutation AddCommentToRecipe1 {\n  addNewComment(comment: { recipeId: \"1\", nickname: \"MichalLytek\", content: \"Nice one!\" })\n}\n\nmutation AddCommentToRecipe2 {\n  addNewComment(comment: { recipeId: \"2\", nickname: \"MichalLytek\", content: \"Nice two!\" })\n}\n\nsubscription NewCommentsForRecipe2 {\n  newComments(recipeId: \"2\") {\n    nickname\n    content\n    date\n  }\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/index.ts",
    "content": "import \"reflect-metadata\";\nimport \"dotenv/config\";\nimport http from \"node:http\";\nimport path from \"node:path\";\nimport { createYoga } from \"graphql-yoga\";\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Publish/Subscribe\n    pubSub,\n    validate: false,\n  });\n\n  // Create GraphQL server\n  const yoga = createYoga({\n    schema,\n    graphqlEndpoint: \"/graphql\",\n  });\n\n  // Create server\n  const httpServer = http.createServer(yoga);\n\n  // Start server\n  httpServer.listen(4000, () => {\n    console.log(`GraphQL server ready at http://localhost:4000/graphql`);\n  });\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/redis-subscriptions/pubsub.ts",
    "content": "import { createRedisEventTarget } from \"@graphql-yoga/redis-event-target\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport { Redis } from \"ioredis\";\nimport { type NewCommentPayload } from \"./comment.type\";\n\nconst redisUrl = process.env.REDIS_URL;\nif (!redisUrl) {\n  throw new Error(\"REDIS_URL env variable is not defined\");\n}\n\nexport const enum Topic {\n  NEW_COMMENT = \"NEW_COMMENT\",\n}\n\nexport const pubSub = createPubSub<{\n  [Topic.NEW_COMMENT]: [NewCommentPayload];\n}>({\n  eventTarget: createRedisEventTarget({\n    publishClient: new Redis(redisUrl, {\n      retryStrategy: times => Math.max(times * 100, 3000),\n    }),\n    subscribeClient: new Redis(redisUrl, {\n      retryStrategy: times => Math.max(times * 100, 3000),\n    }),\n  }),\n});\n"
  },
  {
    "path": "examples/redis-subscriptions/recipe.data.ts",
    "content": "import { Comment } from \"./comment.type\";\nimport { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nfunction createComment(commentData: Partial<Comment>): Comment {\n  return Object.assign(new Comment(), commentData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    id: \"1\",\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    comments: [\n      createComment({\n        date: new Date(\"2018-03-21\"),\n        content: \"Very tasty!\",\n        nickname: \"Anonymous\",\n      }),\n      createComment({\n        date: new Date(\"2018-01-12\"),\n        content: \"Not so tasty!\",\n        nickname: \"Anonymous again\",\n      }),\n    ],\n  }),\n  createRecipe({\n    id: \"2\",\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    comments: [\n      createComment({\n        date: new Date(),\n        content: \"Very good, very cheap!\",\n        nickname: \"Master of cooking\",\n      }),\n    ],\n  }),\n  createRecipe({\n    id: \"3\",\n    title: \"Recipe 3\",\n    comments: [],\n  }),\n];\n"
  },
  {
    "path": "examples/redis-subscriptions/recipe.resolver.args.ts",
    "content": "import { ArgsType, Field, ID } from \"type-graphql\";\n\n@ArgsType()\nexport class NewCommentsArgs {\n  @Field(_type => ID)\n  recipeId!: string;\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/recipe.resolver.ts",
    "content": "import {\n  Arg,\n  Args,\n  ID,\n  Mutation,\n  Query,\n  Resolver,\n  Root,\n  Subscription,\n  type SubscriptionHandlerData,\n} from \"type-graphql\";\nimport { CommentInput } from \"./comment.input\";\nimport { Comment, NewCommentPayload } from \"./comment.type\";\nimport { Topic, pubSub } from \"./pubsub\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { NewCommentsArgs } from \"./recipe.resolver.args\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver()\nexport class RecipeResolver {\n  private readonly recipes: Recipe[] = sampleRecipes.slice();\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"id\", _type => ID) id: string) {\n    return this.recipes.find(recipe => recipe.id === id);\n  }\n\n  @Mutation(_returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput): Promise<boolean> {\n    const recipe = this.recipes.find(r => r.id === input.recipeId);\n    if (!recipe) {\n      return false;\n    }\n\n    const comment: Comment = {\n      content: input.content,\n      nickname: input.nickname,\n      date: new Date(),\n    };\n    recipe.comments.push(comment);\n\n    pubSub.publish(Topic.NEW_COMMENT, {\n      content: comment.content,\n      nickname: comment.nickname,\n      dateString: comment.date.toISOString(),\n      recipeId: input.recipeId,\n    });\n\n    return true;\n  }\n\n  @Subscription(_returns => Comment, {\n    topics: Topic.NEW_COMMENT,\n    filter: ({ payload, args }: SubscriptionHandlerData<NewCommentPayload, NewCommentsArgs>) =>\n      payload.recipeId === args.recipeId,\n  })\n  newComments(@Root() newComment: NewCommentPayload, @Args() _args: NewCommentsArgs): Comment {\n    return {\n      content: newComment.content,\n      date: new Date(newComment.dateString), // Limitation of Redis payload serialization\n      nickname: newComment.nickname,\n    } satisfies Comment;\n  }\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/recipe.type.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\nimport { Comment } from \"./comment.type\";\n\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Comment])\n  comments!: Comment[];\n}\n"
  },
  {
    "path": "examples/redis-subscriptions/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Comment {\n  content: String!\n  date: DateTimeISO!\n  nickname: String\n}\n\ninput CommentInput {\n  content: String!\n  nickname: String\n  recipeId: ID!\n}\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addNewComment(comment: CommentInput!): Boolean!\n}\n\ntype Query {\n  recipe(id: ID!): Recipe\n}\n\ntype Recipe {\n  comments: [Comment!]!\n  description: String\n  id: ID!\n  title: String!\n}\n\ntype Subscription {\n  newComments(recipeId: ID!): Comment!\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/examples.graphql",
    "content": "query AllPersons {\n  persons {\n    id\n    name\n    age\n    role\n  }\n}\n\nquery OneRecipe {\n  recipe(id: 1) {\n    uuid\n    title\n    ratings\n    averageRating\n  }\n}\n\nmutation PromotePersonOne {\n  promote(personId: 1)\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { Container } from \"typedi\";\nimport { PersonResolver } from \"./person\";\nimport { RecipeResolver } from \"./recipe\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver, PersonResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Registry 3rd party IOC container\n    container: Container,\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/resolvers-inheritance/person/index.ts",
    "content": "export * from \"./person.resolver\";\nexport * from \"./person.role\";\nexport * from \"./person.type\";\n"
  },
  {
    "path": "examples/resolvers-inheritance/person/person.resolver.ts",
    "content": "import { Arg, Int, Mutation, Resolver } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { PersonRole } from \"./person.role\";\nimport { Person } from \"./person.type\";\nimport { ResourceResolver } from \"../resource\";\n\nconst persons: Person[] = [\n  {\n    id: 1,\n    name: \"Person 1\",\n    age: 23,\n    role: PersonRole.Normal,\n  },\n  {\n    id: 2,\n    name: \"Person 2\",\n    age: 48,\n    role: PersonRole.Admin,\n  },\n];\n\n@Resolver()\n@Service()\nexport class PersonResolver extends ResourceResolver(Person, persons) {\n  // Here you can add resource-specific operations\n\n  @Mutation()\n  promote(@Arg(\"personId\", _type => Int) personId: number): boolean {\n    // Full access to base resolver class fields and methods\n\n    const person = this.resourceService.getOne(personId);\n    if (!person) {\n      throw new Error(\"Person not found!\");\n    }\n\n    if (person.role === PersonRole.Normal) {\n      person.role = PersonRole.Pro;\n      return true;\n    }\n\n    return false;\n  }\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/person/person.role.ts",
    "content": "import { registerEnumType } from \"type-graphql\";\n\nexport enum PersonRole {\n  Normal,\n  Pro,\n  Admin,\n}\n\nregisterEnumType(PersonRole, { name: \"PersonRole\" });\n"
  },
  {
    "path": "examples/resolvers-inheritance/person/person.type.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\nimport { PersonRole } from \"./person.role\";\nimport { type Resource } from \"../resource\";\n\n@ObjectType()\nexport class Person implements Resource {\n  @Field()\n  id!: number;\n\n  @Field()\n  name!: string;\n\n  @Field(_type => Int)\n  age!: number;\n\n  @Field(_type => PersonRole)\n  role!: PersonRole;\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/recipe/index.ts",
    "content": "export * from \"./recipe.resolver\";\nexport * from \"./recipe.type\";\n"
  },
  {
    "path": "examples/resolvers-inheritance/recipe/recipe.resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { Recipe } from \"./recipe.type\";\nimport { ResourceResolver } from \"../resource\";\n\nconst recipes: Recipe[] = [\n  {\n    id: 1,\n    title: \"Recipe 1\",\n    ratings: [1, 3, 4],\n  },\n];\n\n@Resolver(_of => Recipe)\n@Service()\nexport class RecipeResolver extends ResourceResolver(Recipe, recipes) {\n  // Here you can add resource-specific operations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe): number {\n    return recipe.ratings.reduce((a, b) => a + b, 0) / recipe.ratings.length;\n  }\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/recipe/recipe.type.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\nimport { type Resource } from \"../resource\";\n\n@ObjectType()\nexport class Recipe implements Resource {\n  @Field()\n  id!: number;\n\n  @Field()\n  title!: string;\n\n  @Field(_type => [Int])\n  ratings!: number[];\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/index.ts",
    "content": "export * from \"./resource.args\";\nexport * from \"./resource\";\nexport * from \"./resource.resolver\";\nexport * from \"./resource.service\";\nexport * from \"./resource.service.factory\";\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/resource.args.ts",
    "content": "import { ArgsType, Field, Int } from \"type-graphql\";\n\n@ArgsType()\nexport class GetAllArgs {\n  @Field(_type => Int)\n  skip = 0;\n\n  @Field(_type => Int)\n  take = 10;\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/resource.resolver.ts",
    "content": "import { Arg, Args, type ClassType, FieldResolver, Int, Query, Resolver, Root } from \"type-graphql\";\nimport { Service } from \"typedi\";\nimport { Resource } from \"./resource\";\nimport { GetAllArgs } from \"./resource.args\";\nimport { type ResourceService } from \"./resource.service\";\nimport { ResourceServiceFactory } from \"./resource.service.factory\";\n\nexport function ResourceResolver<TResource extends Resource>(\n  ResourceCls: ClassType<TResource>,\n  resources: TResource[],\n) {\n  const resourceName = ResourceCls.name.toLocaleLowerCase();\n\n  @Resolver(_of => ResourceCls)\n  @Service()\n  abstract class ResourceResolverClass {\n    protected resourceService: ResourceService<TResource>;\n\n    constructor(factory: ResourceServiceFactory) {\n      this.resourceService = factory.create(resources);\n    }\n\n    @Query(_returns => ResourceCls, { name: `${resourceName}` })\n    protected async getOne(@Arg(\"id\", _type => Int) id: number) {\n      return this.resourceService.getOne(id);\n    }\n\n    @Query(_returns => [ResourceCls], { name: `${resourceName}s` })\n    protected async getAll(@Args() { skip, take }: GetAllArgs) {\n      const all = this.resourceService.getAll(skip, take);\n      return all;\n    }\n\n    // Dynamically created field with resolver for all child resource classes\n    @FieldResolver({ name: \"uuid\" })\n    protected getUuid(@Root() resource: Resource): string {\n      return `${resourceName}_${resource.id}`;\n    }\n  }\n\n  return ResourceResolverClass;\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/resource.service.factory.ts",
    "content": "import { Service } from \"typedi\";\nimport { type Resource } from \"./resource\";\nimport { ResourceService } from \"./resource.service\";\n\n// Use factory to separate instance of service for each generic\n@Service()\nexport class ResourceServiceFactory {\n  create<TResource extends Resource>(resources?: TResource[]) {\n    return new ResourceService(resources);\n  }\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/resource.service.ts",
    "content": "import { type Resource } from \"./resource\";\n\nexport class ResourceService<TResource extends Resource> {\n  constructor(protected resources: TResource[] = []) {}\n\n  getOne(id: number): TResource | undefined {\n    return this.resources.find(res => res.id === id);\n  }\n\n  getAll(skip: number, take: number): TResource[] {\n    const start: number = skip;\n    const end: number = skip + take;\n    return this.resources.slice(start, end);\n  }\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/resource/resource.ts",
    "content": "export interface Resource {\n  id: number;\n}\n"
  },
  {
    "path": "examples/resolvers-inheritance/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  promote(personId: Int!): Boolean!\n}\n\ntype Person {\n  age: Int!\n  id: Float!\n  name: String!\n  role: PersonRole!\n  uuid: String!\n}\n\nenum PersonRole {\n  Admin\n  Normal\n  Pro\n}\n\ntype Query {\n  person(id: Int!): Person!\n  persons(skip: Int! = 0, take: Int! = 10): [Person!]!\n  recipe(id: Int!): Recipe!\n  recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]!\n}\n\ntype Recipe {\n  averageRating: Float!\n  id: Float!\n  ratings: [Int!]!\n  title: String!\n  uuid: String!\n}\n"
  },
  {
    "path": "examples/simple-subscriptions/examples.graphql",
    "content": "subscription AllNotifications {\n  normalSubscription {\n    id\n    message\n    date\n  }\n}\n\nsubscription EvenNotifications {\n  subscriptionWithFilter {\n    id\n    message\n    date\n  }\n}\n\nmutation PublishMessage {\n  pubSubMutation(message: \"Hello\")\n}\n\n# Dynamic topics\n\nsubscription DynamicTopic {\n  subscribeToTopicFromArg(topic: \"FOO_MESSAGES\") {\n    id\n    message\n  }\n}\n\nmutation PublishMessageToDynamicTopic {\n  publishToDynamicTopic(topic: \"FOO_MESSAGES\", message: \"Hi Foo!\")\n}\n\n# Dynamic topic id\n\nsubscription DynamicTopicId {\n  subscribeToTopicIdFromArg(topicId: 2137) {\n    id\n    message\n  }\n}\n\nmutation PublishMessageToDynamicTopicId {\n  publishWithDynamicTopicId(topicId: 2137, message: \"Hi Foo!\")\n}\n"
  },
  {
    "path": "examples/simple-subscriptions/index.ts",
    "content": "import \"reflect-metadata\";\nimport http from \"node:http\";\nimport path from \"node:path\";\nimport { createYoga } from \"graphql-yoga\";\nimport { buildSchema } from \"type-graphql\";\nimport { NotificationResolver } from \"./notification.resolver\";\nimport { pubSub } from \"./pubsub\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [NotificationResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Publish/Subscribe\n    pubSub,\n  });\n\n  // Create GraphQL server\n  const yoga = createYoga({\n    schema,\n    graphqlEndpoint: \"/graphql\",\n  });\n\n  // Create server\n  const httpServer = http.createServer(yoga);\n\n  // Start server\n  httpServer.listen(4000, () => {\n    console.log(`GraphQL server ready at http://localhost:4000/graphql`);\n  });\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/simple-subscriptions/notification.resolver.ts",
    "content": "import {\n  Arg,\n  Int,\n  Mutation,\n  Query,\n  Resolver,\n  Root,\n  type SubscribeResolverData,\n  Subscription,\n  type SubscriptionHandlerData,\n} from \"type-graphql\";\nimport { Notification, NotificationPayload } from \"./notification.type\";\nimport { Topic, pubSub } from \"./pubsub\";\n\n@Resolver()\nexport class NotificationResolver {\n  private id: number = 0;\n\n  @Query(_returns => Date)\n  currentDate() {\n    return new Date();\n  }\n\n  @Mutation(_returns => Boolean)\n  async pubSubMutation(@Arg(\"message\", { nullable: true }) message?: string): Promise<boolean> {\n    this.id += 1;\n    const payload: NotificationPayload = { id: this.id, message };\n    pubSub.publish(Topic.NOTIFICATIONS, payload);\n    return true;\n  }\n\n  @Subscription({ topics: Topic.NOTIFICATIONS })\n  normalSubscription(@Root() { id, message }: NotificationPayload): Notification {\n    return { id, message, date: new Date() };\n  }\n\n  @Subscription(_returns => Notification, {\n    topics: Topic.NOTIFICATIONS,\n    filter: ({ payload }: SubscriptionHandlerData<NotificationPayload>) => payload.id % 2 === 0,\n  })\n  subscriptionWithFilter(@Root() { id, message }: NotificationPayload) {\n    const newNotification: Notification = { id, message, date: new Date() };\n    return newNotification;\n  }\n\n  // Multiple topics\n\n  @Subscription(_returns => Notification, {\n    topics: [Topic.NOTIFICATIONS, \"NOTIFICATIONS_2\"],\n    filter: ({ payload }: SubscriptionHandlerData<NotificationPayload>) => payload.id % 2 === 0,\n  })\n  subscriptionWithMultipleTopics(@Root() { id, message }: NotificationPayload) {\n    const newNotification: Notification = { id, message, date: new Date() };\n    return newNotification;\n  }\n\n  // Dynamic topic\n\n  @Mutation(() => Boolean)\n  async publishToDynamicTopic(\n    @Arg(\"topic\") topic: string,\n    @Arg(\"message\", { nullable: true }) message?: string,\n  ): Promise<boolean> {\n    this.id += 1;\n    const payload: NotificationPayload = { id: this.id, message };\n    pubSub.publish(topic, payload);\n    return true;\n  }\n\n  @Subscription({\n    topics: ({ args }) => args.topic,\n  })\n  subscribeToTopicFromArg(\n    @Arg(\"topic\") _topic: string,\n    @Root() { id, message }: NotificationPayload,\n  ): Notification {\n    return { id, message, date: new Date() };\n  }\n\n  // Dynamic topic id\n\n  @Mutation(() => Boolean)\n  async publishWithDynamicTopicId(\n    @Arg(\"topicId\", () => Int) topicId: number,\n    @Arg(\"message\", { nullable: true }) message?: string,\n  ): Promise<boolean> {\n    this.id += 1;\n    const payload: NotificationPayload = { id: this.id, message };\n    pubSub.publish(Topic.DYNAMIC_ID_TOPIC, topicId, payload);\n    return true;\n  }\n\n  @Subscription({\n    topics: Topic.DYNAMIC_ID_TOPIC,\n    topicId: ({ args }: SubscribeResolverData<any, { topicId: number }, any>) => args.topicId,\n  })\n  subscribeToTopicIdFromArg(\n    @Arg(\"topicId\", () => Int) _topicId: number,\n    @Root() { id, message }: NotificationPayload,\n  ): Notification {\n    return { id, message, date: new Date() };\n  }\n}\n"
  },
  {
    "path": "examples/simple-subscriptions/notification.type.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Notification {\n  @Field(_type => ID)\n  id!: number;\n\n  @Field({ nullable: true })\n  message?: string;\n\n  @Field(_type => Date)\n  date!: Date;\n}\n\nexport interface NotificationPayload {\n  id: number;\n\n  message?: string;\n}\n"
  },
  {
    "path": "examples/simple-subscriptions/pubsub.ts",
    "content": "import { createPubSub } from \"@graphql-yoga/subscription\";\nimport { type NotificationPayload } from \"./notification.type\";\n\nexport const enum Topic {\n  NOTIFICATIONS = \"NOTIFICATIONS\",\n  DYNAMIC_ID_TOPIC = \"DYNAMIC_ID_TOPIC\",\n}\n\nexport const pubSub = createPubSub<\n  {\n    [Topic.NOTIFICATIONS]: [NotificationPayload];\n    [Topic.DYNAMIC_ID_TOPIC]: [number, NotificationPayload];\n  } & Record<string, [NotificationPayload]> // Fallback for dynamic topics\n>();\n"
  },
  {
    "path": "examples/simple-subscriptions/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  pubSubMutation(message: String): Boolean!\n  publishToDynamicTopic(message: String, topic: String!): Boolean!\n  publishWithDynamicTopicId(message: String, topicId: Int!): Boolean!\n}\n\ntype Notification {\n  date: DateTimeISO!\n  id: ID!\n  message: String\n}\n\ntype Query {\n  currentDate: DateTimeISO!\n}\n\ntype Subscription {\n  normalSubscription: Notification!\n  subscribeToTopicFromArg(topic: String!): Notification!\n  subscribeToTopicIdFromArg(topicId: Int!): Notification!\n  subscriptionWithFilter: Notification!\n  subscriptionWithMultipleTopics: Notification!\n}\n"
  },
  {
    "path": "examples/simple-usage/examples.graphql",
    "content": "query GetRecipe1 {\n  recipe(title: \"Recipe 1\") {\n    title\n    description\n    ratings\n    creationDate\n    ratingsCount(minRate: 2)\n    averageRating\n  }\n}\n\nquery GetRecipes {\n  recipes {\n    title\n    description\n    creationDate\n    averageRating\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New recipe\", description: \"Simple description\" }) {\n    creationDate\n  }\n}\n"
  },
  {
    "path": "examples/simple-usage/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/simple-usage/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>) {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport function createRecipeSamples() {\n  return [\n    createRecipe({\n      description: \"Desc 1\",\n      title: \"Recipe 1\",\n      ratings: [0, 3, 1],\n      creationDate: new Date(\"2018-04-11\"),\n    }),\n    createRecipe({\n      description: \"Desc 2\",\n      title: \"Recipe 2\",\n      ratings: [4, 2, 3, 1],\n      creationDate: new Date(\"2018-04-15\"),\n    }),\n    createRecipe({\n      description: \"Desc 3\",\n      title: \"Recipe 3\",\n      ratings: [5, 4],\n      creationDate: new Date(),\n    }),\n  ];\n}\n"
  },
  {
    "path": "examples/simple-usage/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n"
  },
  {
    "path": "examples/simple-usage/recipe.resolver.ts",
    "content": "import {\n  Arg,\n  FieldResolver,\n  Int,\n  Mutation,\n  Query,\n  Resolver,\n  type ResolverInterface,\n  Root,\n} from \"type-graphql\";\nimport { createRecipeSamples } from \"./recipe.data\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver implements ResolverInterface<Recipe> {\n  private readonly items: Recipe[] = createRecipeSamples();\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"title\") title: string): Promise<Recipe | undefined> {\n    return this.items.find(recipe => recipe.title === title);\n  }\n\n  @Query(_returns => [Recipe], { description: \"Get all the recipes from around the world \" })\n  async recipes(): Promise<Recipe[]> {\n    return this.items;\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipeInput: RecipeInput): Promise<Recipe> {\n    const recipe = Object.assign(new Recipe(), {\n      description: recipeInput.description,\n      title: recipeInput.title,\n      ratings: [],\n      creationDate: new Date(),\n    });\n    await this.items.push(recipe);\n\n    return recipe;\n  }\n\n  @FieldResolver()\n  ratingsCount(\n    @Root() recipe: Recipe,\n    @Arg(\"minRate\", _type => Int, { defaultValue: 0 }) minRate: number,\n  ): number {\n    return recipe.ratings.filter(rating => rating >= minRate).length;\n  }\n}\n"
  },
  {
    "path": "examples/simple-usage/recipe.type.ts",
    "content": "import { Field, Float, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType({ description: \"Object representing cooking recipe\" })\nexport class Recipe {\n  @Field()\n  title!: string;\n\n  @Field(_type => String, { nullable: true, deprecationReason: \"Use 'description' field instead\" })\n  get specification(): string | undefined {\n    return this.description;\n  }\n\n  @Field({ nullable: true, description: \"The recipe description with preparation info\" })\n  description?: string;\n\n  @Field(_type => [Int])\n  ratings!: number[];\n\n  @Field()\n  creationDate!: Date;\n\n  @Field(_type => Int)\n  ratingsCount!: number;\n\n  @Field(_type => Float, { nullable: true })\n  get averageRating(): number | null {\n    const ratingsCount = this.ratings.length;\n    if (ratingsCount === 0) {\n      return null;\n    }\n    const ratingsSum = this.ratings.reduce((a, b) => a + b, 0);\n\n    return ratingsSum / ratingsCount;\n  }\n}\n"
  },
  {
    "path": "examples/simple-usage/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipe(title: String!): Recipe\n\n  \"\"\"\n  Get all the recipes from around the world\n  \"\"\"\n  recipes: [Recipe!]!\n}\n\n\"\"\"\nObject representing cooking recipe\n\"\"\"\ntype Recipe {\n  averageRating: Float\n  creationDate: DateTimeISO!\n\n  \"\"\"\n  The recipe description with preparation info\n  \"\"\"\n  description: String\n  ratings: [Int!]!\n  ratingsCount(minRate: Int! = 0): Int!\n  specification: String @deprecated(reason: \"Use 'description' field instead\")\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n"
  },
  {
    "path": "examples/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.cjs.json\",\n  \"include\": [\"../src\", \"./\"],\n  \"compilerOptions\": {\n    \"emitDecoratorMetadata\": true\n  }\n}\n"
  },
  {
    "path": "examples/tsyringe/examples.graphql",
    "content": "query GetRecipe1 {\n  recipe(recipeId: \"1\") {\n    title\n    description\n    ingredients\n    numberInCollection\n  }\n}\n\nquery GetRecipes {\n  recipes {\n    title\n    description\n    ingredientsLength\n    numberInCollection\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New recipe\", ingredients: [\"One\", \"Two\", \"Three\"] }) {\n    id\n    numberInCollection\n  }\n}\n"
  },
  {
    "path": "examples/tsyringe/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { container } from \"tsyringe\";\nimport { buildSchema } from \"type-graphql\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\n// Add sample recipes in container\ncontainer.register(\"SAMPLE_RECIPES\", { useValue: sampleRecipes.slice() });\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Registry 3rd party IOC container\n    container: { get: cls => container.resolve(cls) },\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/tsyringe/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    id: \"1\",\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    ingredients: [\"one\", \"two\", \"three\"],\n  }),\n  createRecipe({\n    id: \"2\",\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    ingredients: [\"four\", \"five\", \"six\"],\n  }),\n  createRecipe({\n    id: \"3\",\n    title: \"Recipe 3\",\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n  }),\n];\n"
  },
  {
    "path": "examples/tsyringe/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n}\n"
  },
  {
    "path": "examples/tsyringe/recipe.resolver.ts",
    "content": "import { inject, injectable } from \"tsyringe\";\nimport { Arg, FieldResolver, Mutation, Query, Resolver, Root } from \"type-graphql\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { RecipeService } from \"./recipe.service\";\nimport { Recipe } from \"./recipe.type\";\n\n@injectable()\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Inject service\n    @inject(RecipeService)\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    return this.recipeService.getOne(recipeId);\n  }\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return this.recipeService.getAll();\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipe: RecipeInput): Promise<Recipe> {\n    return this.recipeService.add(recipe);\n  }\n\n  @FieldResolver()\n  async numberInCollection(@Root() recipe: Recipe): Promise<number> {\n    const index = await this.recipeService.findIndex(recipe);\n    return index + 1;\n  }\n}\n"
  },
  {
    "path": "examples/tsyringe/recipe.service.ts",
    "content": "import { inject } from \"tsyringe\";\nimport { type RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\n\nexport class RecipeService {\n  private autoIncrementValue: number;\n\n  constructor(\n    @inject(\"SAMPLE_RECIPES\")\n    private readonly items: Recipe[],\n  ) {\n    this.autoIncrementValue = this.items.length;\n  }\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(it => it.id === id);\n  }\n\n  async add(data: RecipeInput) {\n    const recipe = this.createRecipe(data);\n    this.items.push(recipe);\n\n    return recipe;\n  }\n\n  async findIndex(recipe: Recipe) {\n    return this.items.findIndex(it => it.id === recipe.id);\n  }\n\n  private createRecipe(recipeData: Partial<Recipe>): Recipe {\n    const recipe = Object.assign(new Recipe(), recipeData);\n    recipe.id = this.getId();\n\n    return recipe;\n  }\n\n  private getId(): string {\n    this.autoIncrementValue += 1;\n\n    return this.autoIncrementValue.toString();\n  }\n}\n"
  },
  {
    "path": "examples/tsyringe/recipe.type.ts",
    "content": "import { Field, ID, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n\n  @Field(_type => Int)\n  protected numberInCollection!: number;\n\n  @Field(_type => Int)\n  protected get ingredientsLength(): number {\n    return this.ingredients.length;\n  }\n}\n"
  },
  {
    "path": "examples/tsyringe/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: String!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  description: String\n  id: ID!\n  ingredients: [String!]!\n  ingredientsLength: Int!\n  numberInCollection: Int!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  ingredients: [String!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/typegoose/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"no-underscore-dangle\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/typegoose/context.type.ts",
    "content": "import { type User } from \"./entities\";\n\nexport interface Context {\n  user: User;\n}\n"
  },
  {
    "path": "examples/typegoose/entities/index.ts",
    "content": "export * from \"./rating\";\nexport * from \"./recipe\";\nexport * from \"./user\";\n"
  },
  {
    "path": "examples/typegoose/entities/rating.ts",
    "content": "import { prop as Property } from \"@typegoose/typegoose\";\nimport { Field, Int, ObjectType } from \"type-graphql\";\nimport { User } from \"./user\";\nimport { Ref } from \"../types\";\n\n@ObjectType()\nexport class Rating {\n  @Field(_type => Int)\n  @Property({ required: true })\n  value!: number;\n\n  @Field()\n  @Property({ default: new Date(), required: true })\n  date!: Date;\n\n  @Field(_type => User)\n  @Property({ ref: User, required: true })\n  user!: Ref<User>;\n}\n"
  },
  {
    "path": "examples/typegoose/entities/recipe.ts",
    "content": "import { prop as Property, getModelForClass } from \"@typegoose/typegoose\";\nimport { Types } from \"mongoose\";\nimport { Field, ObjectType } from \"type-graphql\";\nimport { Rating } from \"./rating\";\nimport { User } from \"./user\";\nimport { Ref } from \"../types\";\n\n@ObjectType()\nexport class Recipe {\n  @Field()\n  readonly _id!: Types.ObjectId;\n\n  @Field()\n  @Property({ required: true })\n  title!: string;\n\n  @Field({ nullable: true })\n  @Property()\n  description?: string;\n\n  @Field(_type => [Rating])\n  @Property({ type: () => Rating, default: [] })\n  ratings!: Rating[];\n\n  @Field(_type => User)\n  @Property({ ref: User, required: true })\n  author!: Ref<User>;\n}\n\nexport const RecipeModel = getModelForClass(Recipe);\n"
  },
  {
    "path": "examples/typegoose/entities/user.ts",
    "content": "import { prop as Property, getModelForClass } from \"@typegoose/typegoose\";\nimport { Types } from \"mongoose\";\nimport { Field, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class User {\n  @Field()\n  readonly _id!: Types.ObjectId;\n\n  @Field()\n  @Property({ required: true })\n  email!: string;\n\n  @Field({ nullable: true })\n  @Property()\n  nickname?: string;\n\n  @Property({ required: true })\n  password!: string;\n}\n\nexport const UserModel = getModelForClass(User);\n"
  },
  {
    "path": "examples/typegoose/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    _id\n    title\n    author {\n      email\n    }\n    ratings {\n      value\n    }\n  }\n}\n\nquery GetRecipe {\n  # Fill with correct ObjectId\n  recipe(recipeId: \"64551384aac388414b391778\") {\n    _id\n    title\n    ratings {\n      value\n      user {\n        nickname\n      }\n      date\n    }\n    author {\n      _id\n      nickname\n      email\n    }\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New Recipe\" }) {\n    _id\n    ratings {\n      value\n    }\n    author {\n      nickname\n    }\n  }\n}\n\nmutation RatingRecipe {\n  # Fill with correct ObjectId\n  rating(rating: { recipeId: \"64557478aac388414b391799\", value: 4 }) {\n    _id\n    ratings {\n      value\n      user {\n        email\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "examples/typegoose/helpers.ts",
    "content": "import { RecipeModel, type User, UserModel } from \"./entities\";\n\nexport async function seedDatabase() {\n  const defaultUser = new UserModel({\n    email: \"admin@github.com\",\n    nickname: \"administrator\",\n    password: \"s3cr3tp4ssw0rd\",\n  } as User);\n  await defaultUser.save();\n\n  await RecipeModel.create([\n    {\n      title: \"Recipe 1\",\n      description: \"Desc 1\",\n      author: defaultUser._id,\n      ratings: [\n        { value: 2, user: defaultUser._id },\n        { value: 4, user: defaultUser._id },\n        { value: 5, user: defaultUser._id },\n        { value: 3, user: defaultUser._id },\n        { value: 4, user: defaultUser._id },\n      ],\n    },\n    {\n      title: \"Recipe 2\",\n      author: defaultUser._id,\n      ratings: [\n        { value: 2, user: defaultUser._id },\n        { value: 4, user: defaultUser._id },\n      ],\n    },\n  ]);\n\n  return { defaultUser };\n}\n"
  },
  {
    "path": "examples/typegoose/index.ts",
    "content": "import \"reflect-metadata\";\nimport \"dotenv/config\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Types, connect } from \"mongoose\";\nimport { buildSchema } from \"type-graphql\";\nimport { type Context } from \"./context.type\";\nimport { seedDatabase } from \"./helpers\";\nimport { ObjectIdScalar } from \"./object-id.scalar\";\nimport { RatingResolver, RecipeResolver } from \"./resolvers\";\nimport { TypegooseMiddleware } from \"./typegoose.middleware\";\n\nasync function bootstrap() {\n  // Create mongoose connection\n  const mongoose = await connect(process.env.DATABASE_URL!);\n\n  // Clean database\n  await mongoose.connection.db?.dropDatabase();\n  // Seed database with some data\n  const { defaultUser } = await seedDatabase();\n\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver, RatingResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n    // Use document converting middleware\n    globalMiddlewares: [TypegooseMiddleware],\n    // Use ObjectId scalar mapping\n    scalarsMap: [{ type: Types.ObjectId, scalar: ObjectIdScalar }],\n    validate: false,\n  });\n\n  // Create mocked context\n  const context: Context = { user: defaultUser };\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    context: async () => context,\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/typegoose/object-id.scalar.ts",
    "content": "import { GraphQLScalarType, Kind } from \"graphql\";\nimport { Types } from \"mongoose\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  serialize(value: unknown): string {\n    if (!(value instanceof Types.ObjectId)) {\n      throw new Error(\"ObjectIdScalar can only serialize ObjectId values\");\n    }\n    return value.toHexString();\n  },\n  parseValue(value: unknown): Types.ObjectId {\n    if (typeof value !== \"string\") {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new Types.ObjectId(value);\n  },\n  parseLiteral(ast): Types.ObjectId {\n    if (ast.kind !== Kind.STRING) {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new Types.ObjectId(ast.value);\n  },\n});\n"
  },
  {
    "path": "examples/typegoose/resolvers/index.ts",
    "content": "export * from \"./rating.resolver\";\nexport * from \"./recipe.resolver\";\n"
  },
  {
    "path": "examples/typegoose/resolvers/rating.resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { Rating, type User, UserModel } from \"../entities\";\n\n@Resolver(_of => Rating)\nexport class RatingResolver {\n  @FieldResolver()\n  async user(@Root() rating: Rating): Promise<User> {\n    return (await UserModel.findById(rating.user))!;\n  }\n}\n"
  },
  {
    "path": "examples/typegoose/resolvers/recipe.resolver.ts",
    "content": "import { Types } from \"mongoose\";\nimport { Arg, Ctx, FieldResolver, Mutation, Query, Resolver, Root } from \"type-graphql\";\nimport { RatingInput, RecipeInput } from \"./types\";\nimport { Context } from \"../context.type\";\nimport { type Rating, Recipe, RecipeModel, type User, UserModel } from \"../entities\";\nimport { ObjectIdScalar } from \"../object-id.scalar\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  @Query(_returns => Recipe, { nullable: true })\n  recipe(@Arg(\"recipeId\", () => ObjectIdScalar) recipeId: Types.ObjectId) {\n    return RecipeModel.findById(recipeId);\n  }\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return RecipeModel.find({});\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(\n    @Arg(\"recipe\") recipeInput: RecipeInput,\n    @Ctx() { user }: Context,\n  ): Promise<Recipe> {\n    const recipe = new RecipeModel({\n      ...recipeInput,\n      author: user._id,\n    });\n\n    await recipe.save();\n\n    return recipe;\n  }\n\n  @Mutation(_returns => Recipe)\n  async rating(@Arg(\"rating\") ratingInput: RatingInput, @Ctx() { user }: Context): Promise<Recipe> {\n    // Find the recipe\n    const recipe = await RecipeModel.findById(ratingInput.recipeId);\n    if (!recipe) {\n      throw new Error(\"Invalid recipe ID\");\n    }\n\n    // Set the new recipe rating\n    const newRating: Rating = {\n      value: ratingInput.value,\n      user: user._id,\n      date: new Date(),\n    };\n\n    // Add and update the new recipe\n    recipe.ratings.push(newRating);\n    await recipe.save();\n\n    return recipe;\n  }\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe): Promise<User> {\n    return (await UserModel.findById(recipe.author))!;\n  }\n}\n"
  },
  {
    "path": "examples/typegoose/resolvers/types/index.ts",
    "content": "export * from \"./rating.input\";\nexport * from \"./recipe.input\";\n"
  },
  {
    "path": "examples/typegoose/resolvers/types/rating.input.ts",
    "content": "import { Types } from \"mongoose\";\nimport { Field, InputType, Int } from \"type-graphql\";\n\n@InputType()\nexport class RatingInput {\n  @Field()\n  recipeId!: Types.ObjectId;\n\n  @Field(_type => Int)\n  value!: number;\n}\n"
  },
  {
    "path": "examples/typegoose/resolvers/types/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"../../entities\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n"
  },
  {
    "path": "examples/typegoose/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n  rating(rating: RatingInput!): Recipe!\n}\n\n\"\"\"\nMongo object id scalar type\n\"\"\"\nscalar ObjectId\n\ntype Query {\n  recipe(recipeId: ObjectId!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Rating {\n  date: DateTimeISO!\n  user: User!\n  value: Int!\n}\n\ninput RatingInput {\n  recipeId: ObjectId!\n  value: Int!\n}\n\ntype Recipe {\n  author: User!\n  description: String\n  id: ObjectId!\n  ratings: [Rating!]!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n\ntype User {\n  email: String!\n  id: ObjectId!\n  nickname: String\n}\n"
  },
  {
    "path": "examples/typegoose/typegoose.middleware.ts",
    "content": "import { getClass } from \"@typegoose/typegoose\";\nimport { type Document, Model } from \"mongoose\";\nimport { type MiddlewareFn } from \"type-graphql\";\n\nfunction convertDocument(doc: Document) {\n  const convertedDocument = doc.toObject();\n  const DocumentClass = getClass(doc)!;\n  Object.setPrototypeOf(convertedDocument, DocumentClass.prototype);\n  return convertedDocument;\n}\n\nexport const TypegooseMiddleware: MiddlewareFn = async (_, next) => {\n  const result = await next();\n\n  if (Array.isArray(result)) {\n    return result.map(item => (item instanceof Model ? convertDocument(item) : item));\n  }\n\n  if (result instanceof Model) {\n    return convertDocument(result);\n  }\n\n  return result;\n};\n"
  },
  {
    "path": "examples/typegoose/types.ts",
    "content": "import { type Types } from \"mongoose\";\n\nexport type Ref<T> = T | Types.ObjectId;\n"
  },
  {
    "path": "examples/typeorm-basic-usage/context.type.ts",
    "content": "import { type User } from \"./entities\";\n\nexport interface Context {\n  user: User;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/datasource.ts",
    "content": "import * as TypeORM from \"typeorm\";\nimport { Rating, Recipe, User } from \"./entities\";\n\n// Create TypeORM dataSource\nexport const dataSource = new TypeORM.DataSource({\n  type: \"postgres\",\n  url: process.env.DATABASE_URL,\n  synchronize: true,\n  dropSchema: true,\n  cache: true,\n  logging: \"all\",\n  entities: [Rating, Recipe, User],\n  logger: \"advanced-console\",\n});\n"
  },
  {
    "path": "examples/typeorm-basic-usage/entities/index.ts",
    "content": "export * from \"./rating\";\nexport * from \"./recipe\";\nexport * from \"./user\";\n"
  },
  {
    "path": "examples/typeorm-basic-usage/entities/rating.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\nimport {\n  Column,\n  CreateDateColumn,\n  Entity,\n  ManyToOne,\n  PrimaryGeneratedColumn,\n  RelationId,\n} from \"typeorm\";\nimport { Recipe } from \"./recipe\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Rating {\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field(_type => Int)\n  @Column({ type: \"int\" })\n  value!: number;\n\n  @Field(_type => User)\n  @ManyToOne(_type => User)\n  user!: User;\n\n  @RelationId((rating: Rating) => rating.user)\n  userId!: number;\n\n  @Field()\n  @CreateDateColumn()\n  date!: Date;\n\n  @ManyToOne(_type => Recipe)\n  recipe!: Recipe;\n\n  @RelationId((rating: Rating) => rating.recipe)\n  recipeId!: number;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/entities/recipe.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\nimport { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId } from \"typeorm\";\nimport { Rating } from \"./rating\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field()\n  @Column()\n  title!: string;\n\n  @Field({ nullable: true })\n  @Column({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Rating])\n  @OneToMany(_type => Rating, rating => rating.recipe, { cascade: [\"insert\"] })\n  ratings!: Rating[];\n\n  @Field(_type => User)\n  @ManyToOne(_type => User)\n  author!: User;\n\n  @RelationId((recipe: Recipe) => recipe.author)\n  authorId!: number;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/entities/user.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\nimport { Column, Entity, PrimaryGeneratedColumn } from \"typeorm\";\n\n@ObjectType()\n@Entity()\nexport class User {\n  @Field(_type => ID)\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field()\n  @Column()\n  email!: string;\n\n  @Field({ nullable: true })\n  @Column({ nullable: true })\n  nickname?: string;\n\n  @Column()\n  password!: string;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    id\n    title\n    author {\n      email\n    }\n    ratings {\n      value\n    }\n  }\n}\n\nquery GetRecipe {\n  recipe(recipeId: 1) {\n    id\n    title\n    ratings {\n      value\n      user {\n        nickname\n      }\n      date\n    }\n    author {\n      id\n      nickname\n      email\n    }\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New Recipe\" }) {\n    id\n    ratings {\n      value\n    }\n    author {\n      nickname\n    }\n  }\n}\n\nmutation RatingRecipe {\n  rating(rating: { recipeId: 3, value: 4 }) {\n    id\n    ratings {\n      value\n      user {\n        email\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/helpers.ts",
    "content": "import { dataSource } from \"./datasource\";\nimport { Rating, Recipe, User } from \"./entities\";\n\nexport async function seedDatabase() {\n  const recipeRepository = dataSource.getRepository(Recipe);\n  const ratingRepository = dataSource.getRepository(Rating);\n  const userRepository = dataSource.getRepository(User);\n\n  const defaultUser = userRepository.create({\n    email: \"admin@github.com\",\n    nickname: \"administrator\",\n    password: \"s3cr3tp4ssw0rd\",\n  });\n  await userRepository.save(defaultUser);\n\n  const recipes = recipeRepository.create([\n    {\n      title: \"Recipe 1\",\n      description: \"Desc 1\",\n      author: defaultUser,\n      ratings: ratingRepository.create([\n        { value: 2, user: defaultUser },\n        { value: 4, user: defaultUser },\n        { value: 5, user: defaultUser },\n        { value: 3, user: defaultUser },\n        { value: 4, user: defaultUser },\n      ]),\n    },\n    {\n      title: \"Recipe 2\",\n      author: defaultUser,\n      ratings: ratingRepository.create([\n        { value: 2, user: defaultUser },\n        { value: 4, user: defaultUser },\n      ]),\n    },\n  ]);\n  await recipeRepository.save(recipes);\n\n  return {\n    defaultUser,\n  };\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/index.ts",
    "content": "import \"reflect-metadata\";\nimport \"dotenv/config\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { type Context } from \"./context.type\";\nimport { dataSource } from \"./datasource\";\nimport { seedDatabase } from \"./helpers\";\nimport { RatingResolver, RecipeResolver } from \"./resolvers\";\n\nasync function bootstrap() {\n  // Create TypeORM connection\n  await dataSource.initialize();\n\n  // Seed database with some data\n  const { defaultUser } = await seedDatabase();\n\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver, RatingResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create mocked context\n  const context: Context = { user: defaultUser };\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    context: async () => context,\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/index.ts",
    "content": "export * from \"./rating.resolver\";\nexport * from \"./recipe.resolver\";\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/rating.resolver.ts",
    "content": "import { FieldResolver, Resolver, Root } from \"type-graphql\";\nimport { type Repository } from \"typeorm\";\nimport { dataSource } from \"../datasource\";\nimport { Rating, User } from \"../entities\";\n\n@Resolver(_of => Rating)\nexport class RatingResolver {\n  private readonly userRepository: Repository<User>;\n\n  constructor() {\n    this.userRepository = dataSource.getRepository(User);\n  }\n\n  @FieldResolver()\n  async user(@Root() rating: Rating): Promise<User> {\n    return (await this.userRepository.findOne({ where: { id: rating.userId }, cache: 1000 }))!;\n  }\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/recipe.resolver.ts",
    "content": "import { Arg, Ctx, FieldResolver, Int, Mutation, Query, Resolver, Root } from \"type-graphql\";\nimport { type Repository } from \"typeorm\";\nimport { RatingInput, RecipeInput } from \"./types\";\nimport { Context } from \"../context.type\";\nimport { dataSource } from \"../datasource\";\nimport { Rating, Recipe, User } from \"../entities\";\n\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  private readonly ratingRepository: Repository<Rating>;\n\n  private readonly recipeRepository: Repository<Recipe>;\n\n  private readonly userRepository: Repository<User>;\n\n  constructor() {\n    this.ratingRepository = dataSource.getRepository(Rating);\n    this.recipeRepository = dataSource.getRepository(Recipe);\n    this.userRepository = dataSource.getRepository(User);\n  }\n\n  @Query(_returns => Recipe, { nullable: true })\n  recipe(@Arg(\"recipeId\", _type => Int) recipeId: number) {\n    return this.recipeRepository.findOneBy({ id: recipeId });\n  }\n\n  @Query(_returns => [Recipe])\n  recipes(): Promise<Recipe[]> {\n    return this.recipeRepository.find();\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(\n    @Arg(\"recipe\") recipeInput: RecipeInput,\n    @Ctx() { user }: Context,\n  ): Promise<Recipe> {\n    const recipe = this.recipeRepository.create({\n      ...recipeInput,\n      authorId: user.id,\n    });\n    return this.recipeRepository.save(recipe);\n  }\n\n  @Mutation(_returns => Recipe)\n  async rating(@Arg(\"rating\") ratingInput: RatingInput, @Ctx() { user }: Context): Promise<Recipe> {\n    // Find the recipe\n    const recipe = await this.recipeRepository.findOne({\n      where: { id: ratingInput.recipeId },\n      relations: [\"ratings\"],\n    });\n    if (!recipe) {\n      throw new Error(\"Invalid recipe ID\");\n    }\n\n    // Set the new recipe rating\n    const newRating = this.ratingRepository.create({\n      recipe,\n      value: ratingInput.value,\n      user,\n    });\n\n    recipe.ratings.push(newRating);\n\n    // Update and return recipe\n    return this.recipeRepository.save(recipe);\n  }\n\n  @FieldResolver()\n  ratings(@Root() recipe: Recipe) {\n    return this.ratingRepository.find({\n      cache: 1000,\n      where: { recipe: { id: recipe.id } },\n    });\n  }\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe): Promise<User> {\n    return (await this.userRepository.findOne({ where: { id: recipe.authorId }, cache: 1000 }))!;\n  }\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/types/index.ts",
    "content": "export * from \"./rating.input\";\nexport * from \"./recipe.input\";\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/types/rating.input.ts",
    "content": "import { Field, InputType, Int } from \"type-graphql\";\n\n@InputType()\nexport class RatingInput {\n  @Field(_type => Int)\n  recipeId!: number;\n\n  @Field(_type => Int)\n  value!: number;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/resolvers/types/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"../../entities\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n"
  },
  {
    "path": "examples/typeorm-basic-usage/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n  rating(rating: RatingInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: Int!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Rating {\n  date: DateTimeISO!\n  user: User!\n  value: Int!\n}\n\ninput RatingInput {\n  recipeId: Int!\n  value: Int!\n}\n\ntype Recipe {\n  author: User!\n  description: String\n  id: ID!\n  ratings: [Rating!]!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n\ntype User {\n  email: String!\n  id: ID!\n  nickname: String\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/context.type.ts",
    "content": "import { type User } from \"./entities\";\n\nexport interface Context {\n  user: User;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/datasource.ts",
    "content": "import * as TypeORM from \"typeorm\";\nimport { Rating, Recipe, User } from \"./entities\";\n\n// Create TypeORM dataSource\nexport const dataSource = new TypeORM.DataSource({\n  type: \"postgres\",\n  url: process.env.DATABASE_URL,\n  synchronize: true,\n  dropSchema: true,\n  cache: true,\n  logging: \"all\",\n  entities: [Rating, Recipe, User],\n  logger: \"advanced-console\",\n});\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/entities/index.ts",
    "content": "export * from \"./rating\";\nexport * from \"./recipe\";\nexport * from \"./user\";\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/entities/rating.ts",
    "content": "import { Field, Int, ObjectType } from \"type-graphql\";\nimport { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn } from \"typeorm\";\nimport { Recipe } from \"./recipe\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Rating {\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field(_type => Int)\n  @Column({ type: \"int\" })\n  value!: number;\n\n  @Field(_type => User)\n  @ManyToOne(_type => User, { lazy: true })\n  user!: User | Promise<User>;\n\n  @Field()\n  @CreateDateColumn()\n  date!: Date;\n\n  @ManyToOne(_type => Recipe, { lazy: true })\n  recipe!: Recipe | Promise<Recipe>;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/entities/recipe.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\nimport { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from \"typeorm\";\nimport { Rating } from \"./rating\";\nimport { User } from \"./user\";\n\n@Entity()\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field()\n  @Column()\n  title!: string;\n\n  @Field({ nullable: true })\n  @Column({ nullable: true })\n  description?: string;\n\n  @Field(_type => [Rating])\n  @OneToMany(_type => Rating, rating => rating.recipe, { lazy: true, cascade: [\"insert\"] })\n  ratings!: Rating[] | Promise<Rating[]>;\n\n  @Field(_type => User)\n  @ManyToOne(_type => User, { lazy: true })\n  author!: User | Promise<User>;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/entities/user.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\nimport { Column, Entity, OneToMany, PrimaryGeneratedColumn } from \"typeorm\";\nimport { Recipe } from \"./recipe\";\n\n@ObjectType()\n@Entity()\nexport class User {\n  @Field(_type => ID)\n  @PrimaryGeneratedColumn()\n  readonly id!: number;\n\n  @Field()\n  @Column()\n  email!: string;\n\n  @Field({ nullable: true })\n  @Column({ nullable: true })\n  nickname?: string;\n\n  @Column()\n  password!: string;\n\n  @OneToMany(_type => Recipe, recipe => recipe.author, { lazy: true })\n  @Field(_type => [Recipe])\n  recipes!: Recipe[] | Promise<Recipe[]>;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/examples.graphql",
    "content": "query GetRecipes {\n  recipes {\n    id\n    title\n    author {\n      id\n      email\n      nickname\n    }\n    ratings {\n      value\n    }\n  }\n}\n\nquery GetRecipe {\n  recipe(recipeId: 1) {\n    id\n    title\n    ratings {\n      value\n      user {\n        nickname\n      }\n      date\n    }\n    author {\n      nickname\n      recipes {\n        title\n      }\n    }\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New Recipe\" }) {\n    id\n    ratings {\n      value\n    }\n    author {\n      nickname\n    }\n  }\n}\n\nmutation RatingRecipe {\n  rating(rating: { recipeId: 3, value: 4 }) {\n    id\n    ratings {\n      value\n    }\n  }\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/helpers.ts",
    "content": "import { dataSource } from \"./datasource\";\nimport { Rating, Recipe, User } from \"./entities\";\n\nexport async function seedDatabase() {\n  const recipeRepository = dataSource.getRepository(Recipe);\n  const ratingRepository = dataSource.getRepository(Rating);\n  const userRepository = dataSource.getRepository(User);\n\n  const defaultUser = userRepository.create({\n    email: \"admin@github.com\",\n    nickname: \"administrator\",\n    password: \"s3cr3tp4ssw0rd\",\n  });\n  await userRepository.save(defaultUser);\n\n  const [recipe1, recipe2] = recipeRepository.create([\n    {\n      title: \"Recipe 1\",\n      description: \"Desc 1\",\n      author: defaultUser,\n    },\n    {\n      title: \"Recipe 2\",\n      author: defaultUser,\n    },\n  ]);\n  await recipeRepository.save([recipe1, recipe2]);\n\n  const ratings = ratingRepository.create([\n    { value: 2, user: defaultUser, recipe: recipe1 },\n    { value: 4, user: defaultUser, recipe: recipe1 },\n    { value: 5, user: defaultUser, recipe: recipe1 },\n    { value: 3, user: defaultUser, recipe: recipe1 },\n    { value: 4, user: defaultUser, recipe: recipe1 },\n    { value: 2, user: defaultUser, recipe: recipe2 },\n    { value: 4, user: defaultUser, recipe: recipe2 },\n  ]);\n  await ratingRepository.save(ratings);\n\n  return {\n    defaultUser,\n  };\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/index.ts",
    "content": "import \"reflect-metadata\";\nimport \"dotenv/config\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { type Context } from \"./context.type\";\nimport { dataSource } from \"./datasource\";\nimport { seedDatabase } from \"./helpers\";\nimport { RecipeResolver } from \"./resolvers\";\n\nasync function bootstrap() {\n  // Create TypeORM connection\n  await dataSource.initialize();\n\n  // Seed database with some data\n  const { defaultUser } = await seedDatabase();\n\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create mocked context\n  const context: Context = { user: defaultUser };\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    context: async () => context,\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/resolvers/index.ts",
    "content": "export * from \"./recipe.resolver\";\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/resolvers/recipe.resolver.ts",
    "content": "import { Arg, Ctx, Int, Mutation, Query, Resolver } from \"type-graphql\";\nimport { type Repository } from \"typeorm\";\nimport { RatingInput, RecipeInput } from \"./types\";\nimport { Context } from \"../context.type\";\nimport { dataSource } from \"../datasource\";\nimport { Rating, Recipe } from \"../entities\";\n\n@Resolver(Recipe)\nexport class RecipeResolver {\n  private readonly ratingRepository: Repository<Rating>;\n\n  private readonly recipeRepository: Repository<Recipe>;\n\n  constructor() {\n    this.ratingRepository = dataSource.getRepository(Rating);\n    this.recipeRepository = dataSource.getRepository(Recipe);\n  }\n\n  @Query(_returns => Recipe, { nullable: true })\n  recipe(@Arg(\"recipeId\", _type => Int) recipeId: number) {\n    return this.recipeRepository.findOneBy({ id: recipeId });\n  }\n\n  @Query(_returns => [Recipe])\n  recipes(): Promise<Recipe[]> {\n    return this.recipeRepository.find();\n  }\n\n  @Mutation(_returns => Recipe)\n  addRecipe(@Arg(\"recipe\") recipeInput: RecipeInput, @Ctx() { user }: Context): Promise<Recipe> {\n    const recipe = this.recipeRepository.create({\n      ...recipeInput,\n      author: user,\n    });\n    return this.recipeRepository.save(recipe);\n  }\n\n  @Mutation(_returns => Recipe)\n  async rating(@Ctx() { user }: Context, @Arg(\"rating\") rateInput: RatingInput): Promise<Recipe> {\n    // Find the recipe\n    const recipe = await this.recipeRepository.findOne({\n      where: { id: rateInput.recipeId },\n      relations: [\"ratings\"],\n    });\n    if (!recipe) {\n      throw new Error(\"Invalid recipe ID\");\n    }\n\n    // Set the new recipe rating\n    const newRating = this.ratingRepository.create({\n      recipe,\n      user,\n      value: rateInput.value,\n    });\n\n    // Add the new recipe rating\n    (await recipe.ratings).push(newRating);\n\n    // Update and return recipe\n    return this.recipeRepository.save(recipe);\n  }\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/resolvers/types/index.ts",
    "content": "export * from \"./rating.input\";\nexport * from \"./recipe.input\";\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/resolvers/types/rating.input.ts",
    "content": "import { Field, InputType, Int } from \"type-graphql\";\n\n@InputType()\nexport class RatingInput {\n  @Field(_type => Int)\n  recipeId!: number;\n\n  @Field(_type => Int)\n  value!: number;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/resolvers/types/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"../../entities\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description!: string;\n}\n"
  },
  {
    "path": "examples/typeorm-lazy-relations/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n\"\"\"\nA 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.\n\"\"\"\nscalar DateTimeISO\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n  rating(rating: RatingInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: Int!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Rating {\n  date: DateTimeISO!\n  user: User!\n  value: Int!\n}\n\ninput RatingInput {\n  recipeId: Int!\n  value: Int!\n}\n\ntype Recipe {\n  author: User!\n  description: String\n  id: ID!\n  ratings: [Rating!]!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  title: String!\n}\n\ntype User {\n  email: String!\n  id: ID!\n  nickname: String\n  recipes: [Recipe!]!\n}\n"
  },
  {
    "path": "examples/using-container/examples.graphql",
    "content": "query GetRecipe1 {\n  recipe(recipeId: \"1\") {\n    title\n    description\n    ingredients\n    numberInCollection\n  }\n}\n\nquery GetRecipes {\n  recipes {\n    title\n    description\n    ingredientsLength\n    numberInCollection\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New recipe\", ingredients: [\"One\", \"Two\", \"Three\"] }) {\n    id\n    numberInCollection\n  }\n}\n"
  },
  {
    "path": "examples/using-container/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { buildSchema } from \"type-graphql\";\nimport { Container } from \"typedi\";\nimport { sampleRecipes } from \"./recipe.data\";\nimport { RecipeResolver } from \"./recipe.resolver\";\n\n// Add sample recipes in container\nContainer.set({ id: \"SAMPLE_RECIPES\", factory: () => sampleRecipes.slice() });\n\nasync function bootstrap() {\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Registry 3rd party IOC container\n    container: Container,\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/using-container/recipe.data.ts",
    "content": "import { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    id: \"1\",\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    ingredients: [\"one\", \"two\", \"three\"],\n  }),\n  createRecipe({\n    id: \"2\",\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    ingredients: [\"four\", \"five\", \"six\"],\n  }),\n  createRecipe({\n    id: \"3\",\n    title: \"Recipe 3\",\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n  }),\n];\n"
  },
  {
    "path": "examples/using-container/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n}\n"
  },
  {
    "path": "examples/using-container/recipe.resolver.ts",
    "content": "import { Arg, FieldResolver, Mutation, Query, Resolver, Root } from \"type-graphql\";\nimport { Inject, Service } from \"typedi\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { RecipeService } from \"./recipe.service\";\nimport { Recipe } from \"./recipe.type\";\n\n@Service()\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Inject service\n    @Inject()\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    return this.recipeService.getOne(recipeId);\n  }\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    return this.recipeService.getAll();\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipe: RecipeInput): Promise<Recipe> {\n    return this.recipeService.add(recipe);\n  }\n\n  @FieldResolver()\n  async numberInCollection(@Root() recipe: Recipe): Promise<number> {\n    const index = await this.recipeService.findIndex(recipe);\n    return index + 1;\n  }\n}\n"
  },
  {
    "path": "examples/using-container/recipe.service.ts",
    "content": "import { Inject, Service } from \"typedi\";\nimport { type RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\n\n@Service()\nexport class RecipeService {\n  private autoIncrementValue: number;\n\n  constructor(\n    @Inject(\"SAMPLE_RECIPES\")\n    private readonly items: Recipe[],\n  ) {\n    this.autoIncrementValue = this.items.length;\n  }\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(it => it.id === id);\n  }\n\n  async add(data: RecipeInput) {\n    const recipe = this.createRecipe(data);\n    this.items.push(recipe);\n\n    return recipe;\n  }\n\n  async findIndex(recipe: Recipe) {\n    return this.items.findIndex(it => it.id === recipe.id);\n  }\n\n  private createRecipe(recipeData: Partial<Recipe>): Recipe {\n    const recipe = Object.assign(new Recipe(), recipeData);\n    recipe.id = this.getId();\n\n    return recipe;\n  }\n\n  private getId(): string {\n    this.autoIncrementValue += 1;\n\n    return this.autoIncrementValue.toString();\n  }\n}\n"
  },
  {
    "path": "examples/using-container/recipe.type.ts",
    "content": "import { Field, ID, Int, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n\n  @Field(_type => Int)\n  protected numberInCollection!: number;\n\n  @Field(_type => Int)\n  protected get ingredientsLength(): number {\n    return this.ingredients.length;\n  }\n}\n"
  },
  {
    "path": "examples/using-container/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: String!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  description: String\n  id: ID!\n  ingredients: [String!]!\n  ingredientsLength: Int!\n  numberInCollection: Int!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  ingredients: [String!]!\n  title: String!\n}\n"
  },
  {
    "path": "examples/using-scoped-container/context.type.ts",
    "content": "import { type ContainerInstance } from \"typedi\";\n\nexport interface Context {\n  requestId: number;\n  container: ContainerInstance;\n}\n"
  },
  {
    "path": "examples/using-scoped-container/examples.graphql",
    "content": "query GetRecipe1 {\n  recipe(recipeId: \"1\") {\n    title\n    description\n  }\n}\n\nquery GetNotExistingRecipe10 {\n  recipe(recipeId: \"10\") {\n    title\n    description\n  }\n}\n\nquery GetRecipes {\n  recipes {\n    title\n    description\n  }\n}\n\nmutation AddRecipe {\n  addRecipe(recipe: { title: \"New recipe\", ingredients: [\"One\", \"Two\", \"Three\"] }) {\n    id\n    title\n  }\n}\n"
  },
  {
    "path": "examples/using-scoped-container/index.ts",
    "content": "import \"reflect-metadata\";\nimport path from \"node:path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { type ResolverData, buildSchema } from \"type-graphql\";\nimport { Container, type ContainerInstance } from \"typedi\";\nimport { type Context } from \"./context.type\";\nimport { setSamplesInContainer } from \"./recipe/recipe.data\";\nimport { RecipeResolver } from \"./recipe/recipe.resolver\";\n\nasync function bootstrap() {\n  setSamplesInContainer();\n\n  // Build TypeGraphQL executable schema\n  const schema = await buildSchema({\n    // Array of resolvers\n    resolvers: [RecipeResolver],\n    // Registry custom, scoped IOC container from resolver data function\n    container: ({ context }: ResolverData<Context>) => context.container,\n    // Create 'schema.graphql' file with schema definition in current directory\n    emitSchemaFile: path.resolve(__dirname, \"schema.graphql\"),\n  });\n\n  // Create GraphQL server\n  const server = new ApolloServer<Context>({\n    schema,\n    // Create a plugin to allow for disposing the scoped container created for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async willSendResponse(requestContext) {\n            // Dispose the scoped container to prevent memory leaks\n            Container.reset(requestContext.contextValue.requestId.toString());\n\n            // For developers curiosity purpose, here is the logging of current scoped container instances\n            // Make multiple parallel requests to see in console how this works\n            const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n              instance => instance.id,\n            );\n            console.log(\"Instances left in memory: \", instancesIds);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, {\n    listen: { port: 4000 },\n    // Provide unique context with 'requestId' for each request\n    context: async () => {\n      const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n      const container = Container.of(requestId.toString()); // Get scoped container\n      const context = { requestId, container }; // Create context\n      container.set(\"context\", context); // Set context or other data in container\n\n      return context;\n    },\n  });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap().catch(console.error);\n"
  },
  {
    "path": "examples/using-scoped-container/logger.ts",
    "content": "import { Inject, Service } from \"typedi\";\nimport { Context } from \"./context.type\";\n\n// Service is recreated for each request (scoped)\n@Service()\nexport class Logger {\n  constructor(@Inject(\"context\") private readonly context: Context) {\n    console.log(\"Logger created!\");\n  }\n\n  log(...messages: any[]) {\n    console.log(`(ID ${this.context.requestId}):`, ...messages);\n  }\n}\n"
  },
  {
    "path": "examples/using-scoped-container/recipe/recipe.data.ts",
    "content": "import Container from \"typedi\";\nimport { Recipe } from \"./recipe.type\";\n\nfunction createRecipe(recipeData: Partial<Recipe>): Recipe {\n  return Object.assign(new Recipe(), recipeData);\n}\n\nexport const sampleRecipes = [\n  createRecipe({\n    id: \"1\",\n    title: \"Recipe 1\",\n    description: \"Desc 1\",\n    ingredients: [\"one\", \"two\", \"three\"],\n  }),\n  createRecipe({\n    id: \"2\",\n    title: \"Recipe 2\",\n    description: \"Desc 2\",\n    ingredients: [\"four\", \"five\", \"six\"],\n  }),\n  createRecipe({\n    id: \"3\",\n    title: \"Recipe 3\",\n    ingredients: [\"seven\", \"eight\", \"nine\"],\n  }),\n];\n\nexport function setSamplesInContainer() {\n  // Add sample recipes to container\n  Container.set({\n    id: \"SAMPLE_RECIPES\",\n    transient: true, // Create a fresh copy for each 'get' of samples\n    factory: () => {\n      console.log(\"sampleRecipes copy created!\");\n      return sampleRecipes.slice();\n    },\n  });\n}\n"
  },
  {
    "path": "examples/using-scoped-container/recipe/recipe.input.ts",
    "content": "import { Field, InputType } from \"type-graphql\";\nimport { type Recipe } from \"./recipe.type\";\n\n@InputType()\nexport class RecipeInput implements Partial<Recipe> {\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description!: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n}\n"
  },
  {
    "path": "examples/using-scoped-container/recipe/recipe.resolver.ts",
    "content": "import { Arg, Ctx, Mutation, Query, Resolver } from \"type-graphql\";\nimport { Inject, Service } from \"typedi\";\nimport { RecipeInput } from \"./recipe.input\";\nimport { RecipeService } from \"./recipe.service\";\nimport { Recipe } from \"./recipe.type\";\nimport { Context } from \"../context.type\";\nimport { Logger } from \"../logger\";\n\nconst delay = (time: number) =>\n  new Promise(resolve => {\n    setTimeout(resolve, time);\n  });\n\n// Resolver is recreated for each request (scoped)\n@Service()\n@Resolver(_of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    @Inject()\n    private readonly recipeService: RecipeService,\n    @Inject()\n    private readonly logger: Logger,\n  ) {\n    console.log(\"RecipeResolver created!\");\n  }\n\n  @Query(_returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string, @Ctx() { requestId }: Context) {\n    const recipe = await this.recipeService.getOne(recipeId);\n    if (!recipe) {\n      console.log(\"request ID:\", requestId); // Same requestId of logger\n      this.logger.log(`Recipe ${recipeId} not found!`);\n    }\n\n    return recipe;\n  }\n\n  @Query(_returns => [Recipe])\n  async recipes(): Promise<Recipe[]> {\n    await delay(5000); // Simulate delay to allow for manual concurrent requests\n    return this.recipeService.getAll();\n  }\n\n  @Mutation(_returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipe: RecipeInput): Promise<Recipe> {\n    return this.recipeService.add(recipe);\n  }\n}\n"
  },
  {
    "path": "examples/using-scoped-container/recipe/recipe.service.ts",
    "content": "import { Inject, Service } from \"typedi\";\nimport { type RecipeInput } from \"./recipe.input\";\nimport { Recipe } from \"./recipe.type\";\n\n// Service is global, shared by every request\n@Service({ global: true })\nexport class RecipeService {\n  private autoIncrementValue: number;\n\n  constructor(@Inject(\"SAMPLE_RECIPES\") private readonly items: Recipe[]) {\n    console.log(\"RecipeService created!\");\n    this.autoIncrementValue = items.length;\n  }\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(it => it.id === id);\n  }\n\n  async add(data: RecipeInput) {\n    const recipe = this.createRecipe(data);\n    this.items.push(recipe);\n\n    return recipe;\n  }\n\n  private createRecipe(recipeData: Partial<Recipe>): Recipe {\n    const recipe = Object.assign(new Recipe(), {\n      ...recipeData,\n      id: this.getId(),\n    });\n\n    return recipe;\n  }\n\n  private getId(): string {\n    this.autoIncrementValue += 1;\n\n    return this.autoIncrementValue.toString();\n  }\n}\n"
  },
  {
    "path": "examples/using-scoped-container/recipe/recipe.type.ts",
    "content": "import { Field, ID, ObjectType } from \"type-graphql\";\n\n@ObjectType()\nexport class Recipe {\n  @Field(_type => ID)\n  id!: string;\n\n  @Field()\n  title!: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(_type => [String])\n  ingredients!: string[];\n}\n"
  },
  {
    "path": "examples/using-scoped-container/schema.graphql",
    "content": "# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\ntype Mutation {\n  addRecipe(recipe: RecipeInput!): Recipe!\n}\n\ntype Query {\n  recipe(recipeId: String!): Recipe\n  recipes: [Recipe!]!\n}\n\ntype Recipe {\n  description: String\n  id: ID!\n  ingredients: [String!]!\n  title: String!\n}\n\ninput RecipeInput {\n  description: String\n  ingredients: [String!]!\n  title: String!\n}\n"
  },
  {
    "path": "jest.config.cts",
    "content": "import { pathsToModuleNameMapper, JestConfigWithTsJest } from \"ts-jest\";\nimport tsconfig from \"./tsconfig.json\";\n\nexport default {\n  preset: \"ts-jest\",\n  verbose: false,\n  rootDir: \"./\",\n  roots: [\"<rootDir>/src\", \"<rootDir>/tests\"],\n  testEnvironment: \"node\",\n  collectCoverage: false,\n  collectCoverageFrom: [\n    \"<rootDir>/src/**/*.ts\",\n    \"!<rootDir>/src/**/*.d.ts\",\n    \"!<rootDir>/src/shim.ts\",\n  ],\n  moduleNameMapper: pathsToModuleNameMapper(tsconfig.compilerOptions.paths, {\n    prefix: \"<rootDir>\",\n  }),\n  transform: {\n    \"^.+\\\\.tsx?$\": [\"ts-jest\", { tsconfig: \"./tests/tsconfig.json\" }],\n  },\n  testMatch: [\"**/functional/**/*.ts\"],\n  moduleFileExtensions: [\"ts\", \"tsx\", \"js\", \"jsx\", \"json\", \"node\"],\n  coverageDirectory: \"<rootDir>/coverage\",\n} satisfies JestConfigWithTsJest;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"type-graphql\",\n  \"version\": \"2.0.0-rc.4\",\n  \"private\": false,\n  \"description\": \"Create GraphQL schema and resolvers with TypeScript, using classes and decorators!\",\n  \"keywords\": [\n    \"typescript\",\n    \"graphql\",\n    \"schema\",\n    \"resolvers\",\n    \"api\",\n    \"decorators\",\n    \"controllers\",\n    \"apollo\"\n  ],\n  \"homepage\": \"https://typegraphql.com\",\n  \"bugs\": {\n    \"url\": \"https://github.com/MichalLytek/type-graphql/issues\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/MichalLytek/type-graphql.git\"\n  },\n  \"funding\": [\n    {\n      \"type\": \"github\",\n      \"url\": \"https://github.com/sponsors/TypeGraphQL\"\n    },\n    {\n      \"type\": \"opencollective\",\n      \"url\": \"https://opencollective.com/typegraphql\"\n    }\n  ],\n  \"license\": \"MIT\",\n  \"author\": \"Michał Lytek (https://github.com/MichalLytek)\",\n  \"exports\": {\n    \".\": {\n      \"require\": \"./build/cjs/index.js\",\n      \"import\": \"./build/esm/index.js\",\n      \"types\": \"./build/typings/index.d.ts\"\n    },\n    \"./shim\": {\n      \"require\": \"./build/cjs/shim.js\",\n      \"import\": \"./build/esm/shim.js\",\n      \"types\": \"./build/typings/shim.ts\"\n    }\n  },\n  \"main\": \"./build/cjs/index.js\",\n  \"module\": \"./build/esm/index.js\",\n  \"browser\": \"./build/cjs/shim.js\",\n  \"types\": \"./build/typings/index.d.ts\",\n  \"files\": [\n    \"./build\"\n  ],\n  \"scripts\": {\n    \"prebuild\": \"npm run clean:build && npm run check:version\",\n    \"build\": \"npx tsc --build ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.typings.json\",\n    \"postbuild\": \"npx shx rm ./build/typings/shim.d.ts && npx shx cp ./src/shim.ts ./build/typings && npx ts-node ./scripts/package.json.ts\",\n    \"prebuild:benchmarks\": \"npm run clean:build:benchmarks\",\n    \"build:benchmarks\": \"npx tsc --build ./benchmarks/tsconfig.json\",\n    \"check\": \"npx npm-run-all --npm-path npm \\\"check:*\\\"\",\n    \"check:benchmarks\": \"npx tsc --project ./benchmarks/tsconfig.json --noEmit\",\n    \"check:examples\": \"npx tsc --project ./examples/tsconfig.json --noEmit\",\n    \"check:format\": \"npx prettier --check .\",\n    \"check:lint\": \"npx eslint .\",\n    \"check:markdown\": \"npx markdownlint \\\"**/*.md\\\"\",\n    \"check:script\": \"npx shellcheck ./.husky/pre-commit\",\n    \"check:scripts\": \"npx tsc --project ./scripts/tsconfig.json --noEmit\",\n    \"check:spell\": \"npx cspell lint --config cspell.json --no-progress --show-context \\\"**\\\"\",\n    \"check:type\": \"npx npm-run-all --npm-path npm \\\"check:type:*\\\"\",\n    \"check:type:cjs\": \"npx tsc --project ./tsconfig.cjs.json --noEmit\",\n    \"check:type:esm\": \"npx tsc --project ./tsconfig.esm.json --noEmit\",\n    \"check:type:tests\": \"npx tsc --project ./tests/tsconfig.json --noEmit\",\n    \"check:type:typings\": \"npx tsc --project ./tsconfig.typings.json --noEmit --emitDeclarationOnly false\",\n    \"check:version\": \"npx ts-node ./scripts/version.ts\",\n    \"clean\": \"npx npm-run-all --npm-path npm \\\"clean:*\\\"\",\n    \"clean:build\": \"npx shx rm -rf ./build\",\n    \"clean:build:benchmarks\": \"npx shx rm -rf ./benchmarks/build\",\n    \"clean:coverage\": \"npx shx rm -rf ./coverage\",\n    \"prepublishOnly\": \"npm run build && npm run gen:readme\",\n    \"pretest\": \"npm run clean:coverage\",\n    \"test\": \"npx jest --verbose --coverage\",\n    \"test:watch\": \"npx jest --watch\",\n    \"pretest:ci\": \"npm run clean:coverage\",\n    \"test:ci\": \"npx jest --verbose --coverage --ci --forceExit --runInBand\",\n    \"release\": \"npm version --message \\\"release: %s\\\"\",\n    \"version\": \"npm run --prefix ./website new-release --release=$npm_package_version && git add -A .\",\n    \"docs\": \"npm run start --prefix website\",\n    \"fix\": \"npx npm-run-all --npm-path npm \\\"fix:*\\\"\",\n    \"fix:format\": \"npx prettier --write .\",\n    \"fix:lint\": \"npx eslint --fix .\",\n    \"fix:markdown\": \"npx markdownlint --fix \\\"**/*.md\\\"\",\n    \"gen:docs\": \"npx ts-node ./scripts/markdown.ts --on docs\",\n    \"gen:readme\": \"npx ts-node ./scripts/markdown.ts --on readme\",\n    \"gen:sponsorkit\": \"npx sponsorkit --width=320 --dir=./images --name=github-sponsors\",\n    \"postgen:sponsorkit\": \"npx shx cp ./images/github-sponsors.svg ./website/static/img/github-sponsors.svg\",\n    \"prepare\": \"npx ts-patch install -s && npx husky install\"\n  },\n  \"peerDependencies\": {\n    \"class-validator\": \">=0.14.3\",\n    \"graphql\": \"^16.12.0\",\n    \"graphql-scalars\": \"^1.25.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"class-validator\": {\n      \"optional\": true\n    }\n  },\n  \"dependencies\": {\n    \"@graphql-yoga/subscription\": \"^5.0.5\",\n    \"@types/node\": \"*\",\n    \"@types/semver\": \"^7.7.1\",\n    \"graphql-query-complexity\": \"^1.1.0\",\n    \"semver\": \"^7.7.3\",\n    \"tslib\": \"^2.8.1\"\n  },\n  \"devDependencies\": {\n    \"@apollo/cache-control-types\": \"^1.0.3\",\n    \"@apollo/gateway\": \"^2.12.2\",\n    \"@apollo/server\": \"^5.2.0\",\n    \"@apollo/server-plugin-response-cache\": \"^5.0.0\",\n    \"@apollo/subgraph\": \"^2.12.2\",\n    \"@cspell/dict-node\": \"^5.0.8\",\n    \"@cspell/dict-npm\": \"^5.2.27\",\n    \"@cspell/dict-shell\": \"^1.1.2\",\n    \"@cspell/dict-typescript\": \"^3.2.3\",\n    \"@cspell/eslint-plugin\": \"^9.4.0\",\n    \"@graphql-tools/schema\": \"^10.0.30\",\n    \"@graphql-tools/utils\": \"^10.11.0\",\n    \"@graphql-yoga/redis-event-target\": \"^3.0.3\",\n    \"@mikro-orm/core\": \"^6.6.2\",\n    \"@mikro-orm/postgresql\": \"^6.6.2\",\n    \"@typegoose/typegoose\": \"^13.0.0\",\n    \"@types/jest\": \"^30.0.0\",\n    \"@types/lodash.merge\": \"^4.6.9\",\n    \"@types/node\": \"^25.0.3\",\n    \"@types/shelljs\": \"^0.10.0\",\n    \"@types/yargs\": \"^17.0.35\",\n    \"@typescript-eslint/eslint-plugin\": \"^7.18.0\",\n    \"@typescript-eslint/parser\": \"^7.18.0\",\n    \"class-validator\": \"^0.14.3\",\n    \"cspell\": \"^9.4.0\",\n    \"dotenv\": \"^17.2.3\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-config-airbnb-base\": \"^15.0.0\",\n    \"eslint-config-airbnb-typescript\": \"^18.0.0\",\n    \"eslint-config-prettier\": \"^9.1.0\",\n    \"eslint-import-resolver-typescript\": \"^3.6.1\",\n    \"eslint-plugin-import\": \"^2.29.1\",\n    \"eslint-plugin-jest\": \"^28.7.0\",\n    \"eslint-plugin-tsdoc\": \"^0.3.0\",\n    \"expect\": \"^30.2.0\",\n    \"glob\": \"^13.0.0\",\n    \"graphql\": \"^16.12.0\",\n    \"graphql-scalars\": \"^1.25.0\",\n    \"graphql-tag\": \"^2.12.6\",\n    \"graphql-yoga\": \"^5.18.0\",\n    \"husky\": \"^9.1.7\",\n    \"ioredis\": \"^5.8.2\",\n    \"jest\": \"^30.2.0\",\n    \"joiful\": \"^3.0.2\",\n    \"lint-staged\": \"^16.2.7\",\n    \"lodash.merge\": \"^4.6.2\",\n    \"markdownlint\": \"^0.40.0\",\n    \"markdownlint-cli\": \"^0.47.0\",\n    \"mongoose\": \"^9.0.2\",\n    \"npm-run-all\": \"^4.1.5\",\n    \"pg\": \"^8.16.3\",\n    \"prettier\": \"^3.7.4\",\n    \"prettier-plugin-sh\": \"^0.18.0\",\n    \"reflect-metadata\": \"0.1.13\",\n    \"shellcheck\": \"^4.1.0\",\n    \"shelljs\": \"^0.10.0\",\n    \"shx\": \"^0.4.0\",\n    \"sponsorkit\": \"^17.0.0\",\n    \"ts-jest\": \"^29.4.6\",\n    \"ts-node\": \"^10.9.2\",\n    \"ts-patch\": \"^3.3.0\",\n    \"tsconfig-paths\": \"^4.2.0\",\n    \"tsyringe\": \"^4.10.0\",\n    \"typedi\": \"^0.10.0\",\n    \"typeorm\": \"^0.3.28\",\n    \"typescript\": \"^5.5.4\",\n    \"typescript-transform-paths\": \"^3.5.5\",\n    \"typescript-transformer-esm\": \"^1.1.0\",\n    \"yargs\": \"^18.0.0\"\n  },\n  \"engines\": {\n    \"node\": \">= 20.11.1\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\",\n    \"provenance\": true\n  }\n}\n"
  },
  {
    "path": "scripts/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"import/no-extraneous-dependencies\": [\n      \"error\",\n      {\n        \"devDependencies\": true\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "scripts/markdown.ts",
    "content": "#!/usr/bin/env ts-node\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as glob from \"glob\";\nimport { hideBin } from \"yargs/helpers\";\nimport yargs from \"yargs/yargs\";\n\nfunction toUrlPath(\n  filePath: string,\n  relativePath: string,\n  rootPath: string,\n  basePath: string,\n): string {\n  return path.resolve(path.dirname(filePath), relativePath).replace(rootPath, basePath);\n}\n\nfunction escapeRegExp(string: string): string {\n  return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nconst enum Analyze {\n  DOCS = \"docs\",\n  README = \"readme\",\n}\n\nconst gitHubUrl = `https://github.com/MichalLytek/type-graphql/tree`;\nconst gitHubUrlRaw = `https://raw.githubusercontent.com/MichalLytek/type-graphql`;\nconst rootPath = path.resolve(`${__dirname}/..`);\nconst argv = yargs(hideBin(process.argv))\n  .strict()\n  .env(\"TYPE_GRAPHQL\")\n  .usage(\"Markdown\\n\\nUsage: $0 --ref <REF> [options]\")\n  .example([\n    [\"$0 --ref v1.2.3\", \"Use 'v1.2.3' as Git reference\"],\n    [\"TYPE_GRAPHQL_REF=v1.2.3 $0\", \"Use 'v1.2.3' as Git reference\"],\n    [\n      `$0 --ref v1.2.3 --on ${Analyze.README}`,\n      `Use 'v1.2.3' as Git reference and analyze '${Analyze.README}'`,\n    ],\n    [\n      `$0 --ref v1.2.3 --on ${Analyze.README} ${Analyze.DOCS}`,\n      `Use 'v1.2.3' as Git reference and analyze '${Analyze.README}' and '${Analyze.DOCS}'`,\n    ],\n  ])\n  .option(\"ref\", {\n    type: \"string\",\n    demandOption: true,\n    description: \"Git reference\",\n  })\n  .option(\"on\", {\n    type: \"array\",\n    default: [] as Analyze[],\n    requiresArg: true,\n    choices: [Analyze.DOCS, Analyze.README],\n    description: \"Analysis to be performed\",\n  })\n  .check(({ ref, on }) => {\n    if (\n      !/^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(\n        ref,\n      )\n    ) {\n      throw new Error(`Invalid Git reference '${ref}'`);\n    }\n    if (on.length === 0) {\n      throw new Error(`Empty analysis`);\n    }\n\n    return true;\n  })\n  .parseSync();\nconst gitHubUrlRef = `${gitHubUrl}/${argv.ref}`;\nconst gitHubUrlRawRef = `${gitHubUrlRaw}/${argv.ref}`;\n\n// README.md\nif (argv.on.includes(Analyze.README)) {\n  const readmeFile = path.resolve(`${rootPath}/README.md`);\n\n  const readme = fs\n    .readFileSync(readmeFile, { encoding: \"utf8\", flag: \"r\" })\n    .replace(\n      /!\\[([^\\]]*)\\]\\(((?:\\.\\/|\\.\\.\\/).*?)\\)/gm, // ![altText](relativePath)\n      (_, altText, relativePath) =>\n        `![${altText}](${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRawRef)})`,\n    )\n    .replace(\n      /<img([^>]*)\\ssrc=\"((?:\\.\\/|\\.\\.\\/)[^\">]+)\"/gm, // <img attributes src=\"relativePath\"\n      (_, attributes, relativePath) =>\n        `<img${attributes} src=\"${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRawRef)}\"`,\n    )\n    .replace(\n      /(?!\\\\!)\\[([^\\]]*)\\]\\(((?:\\.\\/|\\.\\.\\/).*?)\\)/gm, // [linkText](relativePath)\n      (_, linkText, relativePath) =>\n        `[${linkText}](${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRef)})`,\n    )\n    .replace(\n      /<a([^>]*)\\shref=\"((?:\\.\\/|\\.\\.\\/)[^\">]+)\"/gm, // <a attributes href=\"relativePath\"\n      (_, attributes, relativePath) =>\n        `<a${attributes} href=\"${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRef)}\"`,\n    );\n\n  fs.writeFileSync(readmeFile, readme, { encoding: \"utf8\", flag: \"w\" });\n}\n\n// docs/**/*.md\nif (argv.on.includes(Analyze.DOCS)) {\n  const docFiles = glob.globSync(`${rootPath}/docs/**/*.md`, { absolute: true });\n  const gitHubUrlRefMasterEscaped = escapeRegExp(`${gitHubUrl}/master`);\n\n  for (const docFile of docFiles) {\n    const doc = fs\n      .readFileSync(docFile, { encoding: \"utf8\", flag: \"r\" })\n      .replace(\n        new RegExp(`(?!\\\\!)\\\\[([^\\\\]]*)\\\\]\\\\(${gitHubUrlRefMasterEscaped}\\\\/?(.*?)\\\\)`, \"gm\"), // [linkText](gitHub/relativePath)\n        (_, linkText, relativePath) => `[${linkText}](${gitHubUrlRef}/${relativePath})`,\n      )\n      .replace(\n        new RegExp(`<a([^>]*)\\\\shref=\"${gitHubUrlRefMasterEscaped}\\\\/?([^\">]+)\"`, \"gm\"), // <a attributes href=\"gitHub/relativePath\"\n        (_, attributes, relativePath) => `<a${attributes} href=\"${gitHubUrlRef}/${relativePath}\"`,\n      );\n\n    fs.writeFileSync(docFile, doc, { encoding: \"utf8\", flag: \"w\" });\n  }\n}\n"
  },
  {
    "path": "scripts/package.json.ts",
    "content": "#!/usr/bin/env ts-node\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport expect from \"expect\";\nimport typescript from \"typescript\";\n\ntype TsConfig = Omit<typescript.ParsedCommandLine, \"raw\"> & { raw: { include: string[] } };\n\nfunction readTsConfig(fileName: string): TsConfig {\n  const config = typescript.readConfigFile(fileName, typescript.sys.readFile);\n  expect(config.config).toBeDefined();\n  expect(config.error).toBeUndefined();\n\n  const configJson = typescript.parseJsonConfigFileContent(\n    config.config,\n    typescript.sys,\n    path.dirname(fileName),\n  );\n  expect(configJson.options.outDir).toBeDefined();\n  expect(configJson.raw.include).toBeDefined();\n  expect(Array.isArray(configJson.raw.include)).toBeTruthy();\n  expect(configJson.raw.include.length).toBeGreaterThanOrEqual(1);\n\n  return configJson as TsConfig;\n}\n\nfunction writePackageJson(fileName: string, fileContent: string | NodeJS.ArrayBufferView): void {\n  const fileBasename = path.basename(fileName);\n  const fileDirname = path.dirname(fileName);\n\n  expect(fileBasename).toBe(\"package.json\");\n  if (!fs.existsSync(fileDirname)) {\n    throw new Error(`Directory '${fileDirname}' does not exists`);\n  }\n  if (fs.existsSync(fileName)) {\n    throw new Error(`File '${fileName}' already exists`);\n  }\n\n  fs.writeFileSync(fileName, fileContent, {\n    encoding: \"utf8\",\n    flag: \"w\",\n  });\n}\n\nconst packageJson = JSON.stringify({ type: \"module\" });\nconst tsconfigRoot = readTsConfig(path.resolve(__dirname, \"../tsconfig.esm.json\"));\nconst packageJsonRoot = path.resolve(`${tsconfigRoot.options.outDir}/package.json`);\n\nwritePackageJson(packageJsonRoot, packageJson);\n"
  },
  {
    "path": "scripts/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"noEmit\": true\n  },\n  \"include\": [\".\", \"../src\"]\n}\n"
  },
  {
    "path": "scripts/version.ts",
    "content": "#!/usr/bin/env ts-node\n\nimport packageJson from \"../package.json\";\nimport { graphQLPeerDependencyVersion } from \"../src/utils/graphql-version\";\n\nif (graphQLPeerDependencyVersion !== packageJson.peerDependencies.graphql) {\n  throw new Error(\n    `GraphQL peer dependency version (${graphQLPeerDependencyVersion}) != package.json.peerDependencies.graphql (${packageJson.peerDependencies.graphql})`,\n  );\n}\n"
  },
  {
    "path": "sponsorkit.config.mts",
    "content": "import { BadgePreset, defineConfig } from \"sponsorkit\";\n\nconst presets = {\n  past: {\n    avatar: {\n      size: 20,\n    },\n    boxWidth: 25,\n    boxHeight: 25,\n    container: {\n      sidePadding: 30,\n    },\n  },\n  backers: {\n    avatar: {\n      size: 30,\n    },\n    boxWidth: 35,\n    boxHeight: 35,\n    container: {\n      sidePadding: 30,\n    },\n  },\n  members: {\n    avatar: {\n      size: 45,\n    },\n    boxWidth: 55,\n    boxHeight: 55,\n    container: {\n      sidePadding: 30,\n    },\n  },\n  bronze: {\n    avatar: {\n      size: 75,\n    },\n    boxWidth: 90,\n    boxHeight: 100,\n    container: {\n      sidePadding: 20,\n    },\n    name: {\n      maxLength: 10,\n    },\n  },\n  silver: {\n    avatar: {\n      size: 100,\n    },\n    boxWidth: 105,\n    boxHeight: 125,\n    container: {\n      sidePadding: 20,\n    },\n    name: {\n      maxLength: 16,\n    },\n  },\n  gold: {\n    avatar: {\n      size: 150,\n    },\n    boxWidth: 175,\n    boxHeight: 175,\n    container: {\n      sidePadding: 20,\n    },\n    name: {\n      maxLength: 20,\n    },\n  },\n} satisfies Record<string, BadgePreset>;\n\nexport default defineConfig({\n  includePastSponsors: true,\n  formats: [\"svg\"],\n  github: {\n    login: \"TypeGraphQL\",\n    type: \"organization\",\n  },\n  // opencollective: {\n  //   type: \"collective\",\n  //   slug: \"typegraphql\",\n  // },\n  tiers: [\n    {\n      title: \"Past Sponsors ⏳\",\n      monthlyDollars: -1,\n      preset: presets.past,\n    },\n    {\n      title: \"Backers ☕\",\n      preset: presets.backers,\n    },\n    {\n      title: \"Members 💪\",\n      monthlyDollars: 15,\n      preset: presets.members,\n    },\n    {\n      title: \"Bronze Sponsors 🥉\",\n      monthlyDollars: 50,\n      preset: presets.bronze,\n    },\n    {\n      title: \"Silver Sponsors 🥈\",\n      monthlyDollars: 100,\n      preset: presets.silver,\n    },\n    {\n      title: \"Gold Sponsors 🏆\",\n      monthlyDollars: 300,\n      preset: presets.gold,\n    },\n  ],\n});\n"
  },
  {
    "path": "src/@types/Reflect.d.ts",
    "content": "// Copied from 'reflect-metadata' (https://github.com/rbuckton/reflect-metadata/blob/master/index.d.ts)\n\n/*! *****************************************************************************\nCopyright (C) Microsoft. All rights reserved.\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at http://www.apache.org/licenses/LICENSE-2.0\n\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\nMERCHANTABILITY OR NON-INFRINGEMENT.\n\nSee the Apache Version 2.0 License for specific language governing permissions\nand limitations under the License.\n***************************************************************************** */\n\ndeclare namespace Reflect {\n  function getMetadata(metadataKey: any, target: object): any;\n  /**\n   * Gets the metadata value for the provided metadata key on the target object or its prototype chain.\n   * @param metadataKey - A key used to store and retrieve metadata.\n   * @param target - The target object on which the metadata is defined.\n   * @param propertyKey - The property key for the target.\n   * @returns The metadata value for the metadata key if found; otherwise, `undefined`.\n   * @example\n   *\n   *     class Example \\{\n   *         // property declarations are not part of ES6, though they are valid in TypeScript:\n   *         // static staticProperty;\n   *         // property;\n   *\n   *         static staticMethod(p) \\{ \\}\n   *         method(p) \\{ \\}\n   *     \\}\n   *\n   *     // property (on constructor)\n   *     result = Reflect.getMetadata(\"custom:annotation\", Example, \"staticProperty\");\n   *\n   *     // property (on prototype)\n   *     result = Reflect.getMetadata(\"custom:annotation\", Example.prototype, \"property\");\n   *\n   *     // method (on constructor)\n   *     result = Reflect.getMetadata(\"custom:annotation\", Example, \"staticMethod\");\n   *\n   *     // method (on prototype)\n   *     result = Reflect.getMetadata(\"custom:annotation\", Example.prototype, \"method\");\n   *\n   */\n  function getMetadata(metadataKey: any, target: object, propertyKey: string | symbol): any;\n}\n"
  },
  {
    "path": "src/decorators/Arg.ts",
    "content": "import { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { getParamInfo } from \"@/helpers/params\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator } from \"@/typings\";\nimport {\n  type DecoratorTypeOptions,\n  type DeprecationOptions,\n  type DescriptionOptions,\n  type ReturnTypeFunc,\n  type ValidateOptions,\n} from \"./types\";\n\nexport type ArgOptions = DecoratorTypeOptions &\n  DescriptionOptions &\n  ValidateOptions &\n  DeprecationOptions;\n\nexport function Arg(name: string, options?: ArgOptions): ParameterDecorator;\nexport function Arg(\n  name: string,\n  returnTypeFunc: ReturnTypeFunc,\n  options?: ArgOptions,\n): ParameterDecorator;\nexport function Arg(\n  name: string,\n  returnTypeFuncOrOptions?: ReturnTypeFunc | ArgOptions,\n  maybeOptions?: ArgOptions,\n): ParameterDecorator {\n  return (prototype, propertyKey, parameterIndex) => {\n    const { options, returnTypeFunc } = getTypeDecoratorParams(\n      returnTypeFuncOrOptions,\n      maybeOptions,\n    );\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"arg\",\n      name,\n      description: options.description,\n      deprecationReason: options.deprecationReason,\n      ...getParamInfo({\n        prototype,\n        propertyKey,\n        parameterIndex,\n        returnTypeFunc,\n        options,\n        argName: name,\n      }),\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Args.ts",
    "content": "import { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { getParamInfo } from \"@/helpers/params\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator } from \"@/typings\";\nimport { type ReturnTypeFunc, type ValidateOptions } from \"./types\";\n\nexport function Args(): ParameterDecorator;\nexport function Args(options: ValidateOptions): ParameterDecorator;\nexport function Args(\n  paramTypeFunction: ReturnTypeFunc,\n  options?: ValidateOptions,\n): ParameterDecorator;\nexport function Args(\n  paramTypeFnOrOptions?: ReturnTypeFunc | ValidateOptions,\n  maybeOptions?: ValidateOptions,\n): ParameterDecorator {\n  const { options, returnTypeFunc } = getTypeDecoratorParams(paramTypeFnOrOptions, maybeOptions);\n  return (prototype, propertyKey, parameterIndex) => {\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"args\",\n      ...getParamInfo({ prototype, propertyKey, parameterIndex, returnTypeFunc, options }),\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/ArgsType.ts",
    "content": "import { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\nexport function ArgsType(): ClassDecorator {\n  return target => {\n    getMetadataStorage().collectArgsMetadata({\n      name: target.name,\n      target,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Authorized.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getArrayFromOverloadedRest } from \"@/helpers/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type MethodPropClassDecorator } from \"./types\";\n\nexport function Authorized(): MethodPropClassDecorator;\nexport function Authorized<RoleType = string>(roles: readonly RoleType[]): MethodPropClassDecorator;\nexport function Authorized<RoleType = string>(\n  ...roles: readonly RoleType[]\n): MethodPropClassDecorator;\nexport function Authorized<RoleType = string>(\n  ...rolesOrRolesArray: Array<RoleType | readonly RoleType[]>\n): MethodPropClassDecorator {\n  const roles = getArrayFromOverloadedRest(rolesOrRolesArray);\n\n  return (\n    target: Function | Object,\n    propertyKey?: string | symbol,\n    _descriptor?: TypedPropertyDescriptor<any>,\n  ) => {\n    if (propertyKey == null) {\n      getMetadataStorage().collectAuthorizedResolverMetadata({\n        target: target as Function,\n        roles,\n      });\n      return;\n    }\n\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    getMetadataStorage().collectAuthorizedFieldMetadata({\n      target: target.constructor,\n      fieldName: propertyKey,\n      roles,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Ctx.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator } from \"@/typings\";\n\nexport function Ctx(propertyName?: string): ParameterDecorator {\n  return (prototype, propertyKey, parameterIndex) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"context\",\n      target: prototype.constructor,\n      methodName: propertyKey,\n      index: parameterIndex,\n      propertyName,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Directive.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type MethodAndPropDecorator } from \"./types\";\n\nexport function Directive(\n  sdl: string,\n): MethodAndPropDecorator & ClassDecorator & ParameterDecorator;\nexport function Directive(\n  nameOrDefinition: string,\n): MethodDecorator | PropertyDecorator | ClassDecorator | ParameterDecorator {\n  return (\n    targetOrPrototype: Object,\n    propertyKey: string | symbol | undefined,\n    parameterIndexOrDescriptor: number | TypedPropertyDescriptor<Object>,\n  ) => {\n    const directive = { nameOrDefinition, args: {} };\n\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n    if (propertyKey) {\n      if (typeof parameterIndexOrDescriptor === \"number\") {\n        getMetadataStorage().collectDirectiveArgumentMetadata({\n          target: targetOrPrototype.constructor,\n          fieldName: propertyKey,\n          parameterIndex: parameterIndexOrDescriptor,\n          directive,\n        });\n      } else {\n        getMetadataStorage().collectDirectiveFieldMetadata({\n          target: targetOrPrototype.constructor,\n          fieldName: propertyKey,\n          directive,\n        });\n      }\n    } else {\n      getMetadataStorage().collectDirectiveClassMetadata({\n        target: targetOrPrototype as Function,\n        directive,\n      });\n    }\n  };\n}\n"
  },
  {
    "path": "src/decorators/Extensions.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { type ExtensionsMetadata } from \"@/metadata/definitions\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type MethodAndPropDecorator } from \"./types\";\n\nexport function Extensions(extensions: ExtensionsMetadata): MethodAndPropDecorator & ClassDecorator;\nexport function Extensions(\n  extensions: ExtensionsMetadata,\n): MethodDecorator | PropertyDecorator | ClassDecorator {\n  return (targetOrPrototype, propertyKey, _descriptor) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n    if (propertyKey) {\n      getMetadataStorage().collectExtensionsFieldMetadata({\n        target: targetOrPrototype.constructor,\n        fieldName: propertyKey,\n        extensions,\n      });\n    } else {\n      getMetadataStorage().collectExtensionsClassMetadata({\n        target: targetOrPrototype as Function,\n        extensions,\n      });\n    }\n  };\n}\n"
  },
  {
    "path": "src/decorators/Field.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { findType } from \"@/helpers/findType\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type AdvancedOptions, type MethodAndPropDecorator, type ReturnTypeFunc } from \"./types\";\n\nexport type FieldOptions = AdvancedOptions & {\n  /** Set to `true` to disable auth and all middlewares stack for this field resolver */\n  simple?: boolean;\n};\n\nexport function Field(): MethodAndPropDecorator;\nexport function Field(options: FieldOptions): MethodAndPropDecorator;\nexport function Field(\n  returnTypeFunction?: ReturnTypeFunc,\n  options?: FieldOptions,\n): MethodAndPropDecorator;\nexport function Field(\n  returnTypeFuncOrOptions?: ReturnTypeFunc | FieldOptions,\n  maybeOptions?: FieldOptions,\n): MethodDecorator | PropertyDecorator {\n  return (prototype, propertyKey, descriptor) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    const { options, returnTypeFunc } = getTypeDecoratorParams(\n      returnTypeFuncOrOptions,\n      maybeOptions,\n    );\n    const isResolver = Boolean(descriptor);\n    const isResolverMethod = Boolean(descriptor && descriptor.value);\n\n    const { getType, typeOptions } = findType({\n      metadataKey: isResolverMethod ? \"design:returntype\" : \"design:type\",\n      prototype,\n      propertyKey,\n      returnTypeFunc,\n      typeOptions: options,\n    });\n\n    getMetadataStorage().collectClassFieldMetadata({\n      name: propertyKey,\n      schemaName: options.name || propertyKey,\n      getType,\n      typeOptions,\n      complexity: options.complexity,\n      target: prototype.constructor,\n      description: options.description,\n      deprecationReason: options.deprecationReason,\n      simple: options.simple,\n    });\n\n    if (isResolver) {\n      getMetadataStorage().collectFieldResolverMetadata({\n        kind: \"internal\",\n        methodName: propertyKey,\n        schemaName: options.name || propertyKey,\n        target: prototype.constructor,\n        complexity: options.complexity,\n      });\n    }\n  };\n}\n"
  },
  {
    "path": "src/decorators/FieldResolver.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { findType } from \"@/helpers/findType\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport {\n  type AdvancedOptions,\n  type ReturnTypeFunc,\n  type TypeOptions,\n  type TypeValueThunk,\n} from \"./types\";\n\nexport function FieldResolver(): MethodDecorator;\nexport function FieldResolver(options: AdvancedOptions): MethodDecorator;\nexport function FieldResolver(\n  returnTypeFunction?: ReturnTypeFunc,\n  options?: AdvancedOptions,\n): MethodDecorator;\nexport function FieldResolver(\n  returnTypeFuncOrOptions?: ReturnTypeFunc | AdvancedOptions,\n  maybeOptions?: AdvancedOptions,\n): MethodDecorator {\n  return (prototype, propertyKey) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    let getType: TypeValueThunk | undefined;\n    let typeOptions: TypeOptions | undefined;\n\n    const { options, returnTypeFunc } = getTypeDecoratorParams(\n      returnTypeFuncOrOptions,\n      maybeOptions,\n    );\n\n    // try to get return type info\n    try {\n      const typeInfo = findType({\n        metadataKey: \"design:returntype\",\n        prototype,\n        propertyKey,\n        returnTypeFunc,\n        typeOptions: options,\n      });\n      typeOptions = typeInfo.typeOptions;\n      getType = typeInfo.getType;\n    } catch {\n      /* empty */\n    }\n\n    getMetadataStorage().collectFieldResolverMetadata({\n      kind: \"external\",\n      methodName: propertyKey,\n      schemaName: options.name || propertyKey,\n      target: prototype.constructor,\n      getType,\n      typeOptions,\n      complexity: options.complexity,\n      description: options.description,\n      deprecationReason: options.deprecationReason,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Info.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator } from \"@/typings\";\n\nexport function Info(): ParameterDecorator {\n  return (prototype, propertyKey, parameterIndex) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"info\",\n      target: prototype.constructor,\n      methodName: propertyKey,\n      index: parameterIndex,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/InputType.ts",
    "content": "import { getNameDecoratorParams } from \"@/helpers/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type DescriptionOptions } from \"./types\";\n\nexport type InputTypeOptions = DescriptionOptions;\n\nexport function InputType(): ClassDecorator;\nexport function InputType(options: InputTypeOptions): ClassDecorator;\nexport function InputType(name: string, options?: InputTypeOptions): ClassDecorator;\nexport function InputType(\n  nameOrOptions?: string | InputTypeOptions,\n  maybeOptions?: InputTypeOptions,\n): ClassDecorator {\n  const { name, options } = getNameDecoratorParams(nameOrOptions, maybeOptions);\n  return target => {\n    getMetadataStorage().collectInputMetadata({\n      name: name || target.name,\n      target,\n      description: options.description,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/InterfaceType.ts",
    "content": "import { getNameDecoratorParams } from \"@/helpers/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport {\n  type DescriptionOptions,\n  type ImplementsClassOptions,\n  type ResolveTypeOptions,\n} from \"./types\";\n\nexport type InterfaceTypeOptions = DescriptionOptions &\n  ResolveTypeOptions &\n  ImplementsClassOptions & {\n    /**\n     * Set to false to prevent emitting in schema all object types\n     * that implements this interface type.\n     */\n    autoRegisterImplementations?: boolean;\n  };\n\nexport function InterfaceType(): ClassDecorator;\nexport function InterfaceType(options: InterfaceTypeOptions): ClassDecorator;\nexport function InterfaceType(name: string, options?: InterfaceTypeOptions): ClassDecorator;\nexport function InterfaceType(\n  nameOrOptions?: string | InterfaceTypeOptions,\n  maybeOptions?: InterfaceTypeOptions,\n): ClassDecorator {\n  const { name, options } = getNameDecoratorParams(nameOrOptions, maybeOptions);\n  const interfaceClasses = options.implements && ([] as Function[]).concat(options.implements);\n  return target => {\n    getMetadataStorage().collectInterfaceMetadata({\n      name: name || target.name,\n      target,\n      interfaceClasses,\n      autoRegisteringDisabled: options.autoRegisterImplementations === false,\n      ...options,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Mutation.ts",
    "content": "import { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { getResolverMetadata } from \"@/helpers/resolver-metadata\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type AdvancedOptions, type ReturnTypeFunc } from \"./types\";\n\nexport function Mutation(): MethodDecorator;\nexport function Mutation(options: AdvancedOptions): MethodDecorator;\nexport function Mutation(\n  returnTypeFunc: ReturnTypeFunc,\n  options?: AdvancedOptions,\n): MethodDecorator;\nexport function Mutation(\n  returnTypeFuncOrOptions?: ReturnTypeFunc | AdvancedOptions,\n  maybeOptions?: AdvancedOptions,\n): MethodDecorator {\n  const { options, returnTypeFunc } = getTypeDecoratorParams(returnTypeFuncOrOptions, maybeOptions);\n  return (prototype, methodName) => {\n    const metadata = getResolverMetadata(prototype, methodName, returnTypeFunc, options);\n    getMetadataStorage().collectMutationHandlerMetadata(metadata);\n  };\n}\n"
  },
  {
    "path": "src/decorators/ObjectType.ts",
    "content": "import { getNameDecoratorParams } from \"@/helpers/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type DescriptionOptions, type ImplementsClassOptions } from \"./types\";\n\nexport type ObjectTypeOptions = DescriptionOptions &\n  ImplementsClassOptions & {\n    /** Set to `true` to disable auth and all middlewares stack for all this Object Type fields resolvers */\n    simpleResolvers?: boolean;\n  };\n\nexport function ObjectType(): ClassDecorator;\nexport function ObjectType(options: ObjectTypeOptions): ClassDecorator;\nexport function ObjectType(name: string, options?: ObjectTypeOptions): ClassDecorator;\nexport function ObjectType(\n  nameOrOptions?: string | ObjectTypeOptions,\n  maybeOptions?: ObjectTypeOptions,\n): ClassDecorator {\n  const { name, options } = getNameDecoratorParams(nameOrOptions, maybeOptions);\n  const interfaceClasses = options.implements && ([] as Function[]).concat(options.implements);\n\n  return target => {\n    getMetadataStorage().collectObjectMetadata({\n      name: name || target.name,\n      target,\n      description: options.description,\n      interfaceClasses,\n      simpleResolvers: options.simpleResolvers,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Query.ts",
    "content": "import { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { getResolverMetadata } from \"@/helpers/resolver-metadata\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type AdvancedOptions, type ReturnTypeFunc } from \"./types\";\n\nexport function Query(): MethodDecorator;\nexport function Query(options: AdvancedOptions): MethodDecorator;\nexport function Query(returnTypeFunc: ReturnTypeFunc, options?: AdvancedOptions): MethodDecorator;\nexport function Query(\n  returnTypeFuncOrOptions?: ReturnTypeFunc | AdvancedOptions,\n  maybeOptions?: AdvancedOptions,\n): MethodDecorator {\n  const { options, returnTypeFunc } = getTypeDecoratorParams(returnTypeFuncOrOptions, maybeOptions);\n  return (prototype, methodName) => {\n    const metadata = getResolverMetadata(prototype, methodName, returnTypeFunc, options);\n    getMetadataStorage().collectQueryHandlerMetadata(metadata);\n  };\n}\n"
  },
  {
    "path": "src/decorators/Resolver.ts",
    "content": "import { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ClassType } from \"@/typings\";\nimport { type ClassTypeResolver } from \"./types\";\n\nexport function Resolver(): ClassDecorator;\nexport function Resolver(typeFunc: ClassTypeResolver): ClassDecorator;\nexport function Resolver(objectType: ClassType): ClassDecorator;\nexport function Resolver(objectTypeOrTypeFunc?: Function): ClassDecorator {\n  return target => {\n    // eslint-disable-next-line no-nested-ternary\n    const getObjectType = objectTypeOrTypeFunc\n      ? objectTypeOrTypeFunc.prototype\n        ? () => objectTypeOrTypeFunc as ClassType\n        : (objectTypeOrTypeFunc as ClassTypeResolver)\n      : () => {\n          throw new Error(\n            `No provided object type in '@Resolver' decorator for class '${target.name}!'`,\n          );\n        };\n    getMetadataStorage().collectResolverClassMetadata({\n      target,\n      getObjectType,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Root.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { findType } from \"@/helpers/findType\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator } from \"@/typings\";\nimport { type TypeValueThunk } from \"./types\";\n\nexport function Root(propertyName?: string): ParameterDecorator {\n  return (prototype, propertyKey, parameterIndex) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    let getType: TypeValueThunk | undefined;\n    try {\n      const typeInfo = findType({\n        metadataKey: \"design:paramtypes\",\n        prototype,\n        propertyKey,\n        parameterIndex,\n      });\n      getType = typeInfo.getType;\n    } catch {\n      /* empty */\n    }\n\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"root\",\n      target: prototype.constructor,\n      methodName: propertyKey,\n      index: parameterIndex,\n      propertyName,\n      getType,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/Subscription.ts",
    "content": "import { MissingSubscriptionTopicsError } from \"@/errors\";\nimport { getTypeDecoratorParams } from \"@/helpers/decorators\";\nimport { getResolverMetadata } from \"@/helpers/resolver-metadata\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type MergeExclusive } from \"@/typings\";\nimport {\n  type AdvancedOptions,\n  type ReturnTypeFunc,\n  type SubscriptionFilterFunc,\n  type SubscriptionSubscribeFunc,\n  type SubscriptionTopicIdFunc,\n  type SubscriptionTopicsFunc,\n} from \"./types\";\n\ninterface PubSubOptions {\n  topics: string | string[] | SubscriptionTopicsFunc;\n  topicId?: SubscriptionTopicIdFunc | undefined;\n  filter?: SubscriptionFilterFunc;\n}\n\ninterface SubscribeOptions {\n  subscribe: SubscriptionSubscribeFunc;\n}\n\nexport type SubscriptionOptions = AdvancedOptions & MergeExclusive<PubSubOptions, SubscribeOptions>;\n\nexport function Subscription(options: SubscriptionOptions): MethodDecorator;\nexport function Subscription(\n  returnTypeFunc: ReturnTypeFunc,\n  options: SubscriptionOptions,\n): MethodDecorator;\nexport function Subscription(\n  returnTypeFuncOrOptions: ReturnTypeFunc | SubscriptionOptions,\n  maybeOptions?: SubscriptionOptions,\n): MethodDecorator {\n  const params = getTypeDecoratorParams(returnTypeFuncOrOptions, maybeOptions);\n  const options = params.options as SubscriptionOptions;\n  return (prototype, methodName) => {\n    const metadata = getResolverMetadata(prototype, methodName, params.returnTypeFunc, options);\n    if (Array.isArray(options.topics) && options.topics.length === 0) {\n      throw new MissingSubscriptionTopicsError(metadata.target, metadata.methodName);\n    }\n    getMetadataStorage().collectSubscriptionHandlerMetadata({\n      ...metadata,\n      topics: options.topics,\n      topicId: options.topicId,\n      filter: options.filter,\n      subscribe: options.subscribe,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/UseMiddleware.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getArrayFromOverloadedRest } from \"@/helpers/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type Middleware } from \"@/typings/middleware\";\nimport { type MethodPropClassDecorator } from \"./types\";\n\nexport function UseMiddleware(middlewares: Array<Middleware<any>>): MethodPropClassDecorator;\nexport function UseMiddleware(...middlewares: Array<Middleware<any>>): MethodPropClassDecorator;\nexport function UseMiddleware(\n  ...middlewaresOrMiddlewareArray: Array<Middleware<any> | Array<Middleware<any>>>\n): MethodPropClassDecorator {\n  const middlewares = getArrayFromOverloadedRest(middlewaresOrMiddlewareArray);\n\n  return (\n    target: Function | Object,\n    propertyKey?: string | symbol,\n    _descriptor?: TypedPropertyDescriptor<any>,\n  ) => {\n    if (propertyKey == null) {\n      getMetadataStorage().collectResolverMiddlewareMetadata({\n        target: target as Function,\n        middlewares,\n      });\n      return;\n    }\n\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    getMetadataStorage().collectMiddlewareMetadata({\n      target: target.constructor,\n      fieldName: propertyKey,\n      middlewares,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/createMethodMiddlewareDecorator.ts",
    "content": "import { type MiddlewareFn } from \"@/typings/middleware\";\nimport { UseMiddleware } from \"./UseMiddleware\";\n\nexport function createMethodMiddlewareDecorator<TContextType extends object = object>(\n  resolver: MiddlewareFn<TContextType>,\n): MethodDecorator {\n  return UseMiddleware(resolver);\n}\n"
  },
  {
    "path": "src/decorators/createParameterDecorator.ts",
    "content": "import { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ParameterDecorator, type ResolverData } from \"@/typings\";\nimport { type ArgOptions } from \"./Arg\";\nimport { type ReturnTypeFunc } from \"./types\";\nimport { getParamInfo } from \"../helpers/params\";\nimport { type CustomParamOptions } from \"../metadata/definitions\";\n\nexport interface CustomParameterOptions {\n  arg?: {\n    name: string;\n    typeFunc: ReturnTypeFunc;\n    options?: ArgOptions;\n  };\n}\n\nexport type ParameterResolver<TContextType extends object = object> = (\n  resolverData: ResolverData<TContextType>,\n) => any;\n\nexport function createParameterDecorator<TContextType extends object = object>(\n  resolver: ParameterResolver<TContextType>,\n  paramOptions: CustomParameterOptions = {},\n): ParameterDecorator {\n  return (prototype, propertyKey, parameterIndex) => {\n    if (typeof propertyKey === \"symbol\") {\n      throw new SymbolKeysNotSupportedError();\n    }\n\n    const options: CustomParamOptions = {};\n    if (paramOptions.arg) {\n      options.arg = {\n        kind: \"arg\",\n        name: paramOptions.arg.name,\n        description: paramOptions.arg.options?.description,\n        deprecationReason: paramOptions.arg.options?.deprecationReason,\n        ...getParamInfo({\n          prototype,\n          propertyKey,\n          parameterIndex,\n          returnTypeFunc: paramOptions.arg.typeFunc,\n          options: paramOptions.arg.options,\n          argName: paramOptions.arg.name,\n        }),\n      };\n    }\n\n    getMetadataStorage().collectHandlerParamMetadata({\n      kind: \"custom\",\n      target: prototype.constructor,\n      methodName: propertyKey,\n      index: parameterIndex,\n      resolver,\n      options,\n    });\n  };\n}\n"
  },
  {
    "path": "src/decorators/createResolverClassMiddlewareDecorator.ts",
    "content": "import { type MiddlewareFn } from \"@/typings\";\nimport { UseMiddleware } from \"./UseMiddleware\";\n\nexport function createResolverClassMiddlewareDecorator<TContextType extends object = object>(\n  resolver: MiddlewareFn<TContextType>,\n): ClassDecorator {\n  return UseMiddleware(resolver);\n}\n"
  },
  {
    "path": "src/decorators/enums.ts",
    "content": "import { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type EnumConfig } from \"./types\";\n\nexport function registerEnumType<TEnum extends object>(\n  enumObj: TEnum,\n  enumConfig: EnumConfig<TEnum>,\n) {\n  getMetadataStorage().collectEnumMetadata({\n    enumObj,\n    name: enumConfig.name,\n    description: enumConfig.description,\n    valuesConfig: enumConfig.valuesConfig || {},\n  });\n}\n"
  },
  {
    "path": "src/decorators/index.ts",
    "content": "export type { ArgOptions } from \"./Arg\";\nexport { Arg } from \"./Arg\";\nexport { Args } from \"./Args\";\nexport { ArgsType } from \"./ArgsType\";\nexport { Authorized } from \"./Authorized\";\nexport { createParameterDecorator } from \"./createParameterDecorator\";\nexport { createMethodMiddlewareDecorator } from \"./createMethodMiddlewareDecorator\";\nexport { createResolverClassMiddlewareDecorator } from \"./createResolverClassMiddlewareDecorator\";\nexport { Ctx } from \"./Ctx\";\nexport { Directive } from \"./Directive\";\nexport { Extensions } from \"./Extensions\";\nexport { registerEnumType } from \"./enums\";\nexport type { FieldOptions } from \"./Field\";\nexport { Field } from \"./Field\";\nexport { FieldResolver } from \"./FieldResolver\";\nexport { Info } from \"./Info\";\nexport type { InputTypeOptions } from \"./InputType\";\nexport { InputType } from \"./InputType\";\nexport type { InterfaceTypeOptions } from \"./InterfaceType\";\nexport { InterfaceType } from \"./InterfaceType\";\nexport { Mutation } from \"./Mutation\";\nexport type { ObjectTypeOptions } from \"./ObjectType\";\nexport { ObjectType } from \"./ObjectType\";\nexport { Query } from \"./Query\";\nexport { Resolver } from \"./Resolver\";\nexport { Root } from \"./Root\";\nexport type { SubscriptionOptions } from \"./Subscription\";\nexport { Subscription } from \"./Subscription\";\nexport { createUnionType } from \"./unions\";\nexport { UseMiddleware } from \"./UseMiddleware\";\n"
  },
  {
    "path": "src/decorators/types.ts",
    "content": "import { type GraphQLScalarType } from \"graphql\";\nimport { type ValidateSettings } from \"@/schema/build-context\";\nimport {\n  type ClassType,\n  type Complexity,\n  type MaybePromise,\n  type SubscribeResolverData,\n  type SubscriptionHandlerData,\n  type TypeResolver,\n  type ValidatorFn,\n} from \"@/typings\";\n\nexport type RecursiveArray<TValue> = Array<RecursiveArray<TValue> | TValue>;\n\nexport type TypeValue = ClassType | GraphQLScalarType | Function | object | symbol;\nexport type ReturnTypeFuncValue = TypeValue | RecursiveArray<TypeValue>;\n\nexport type TypeValueThunk = (type?: void) => TypeValue;\nexport type ClassTypeResolver = (of?: void) => ClassType | Function;\n\nexport type ReturnTypeFunc = (returns?: void) => ReturnTypeFuncValue;\n\nexport type SubscriptionFilterFunc = (\n  handlerData: SubscriptionHandlerData<any, any, any>,\n) => boolean | Promise<boolean>;\n\nexport type SubscriptionTopicsFunc = (\n  resolverData: SubscribeResolverData<any, any, any>,\n) => string | string[];\n\nexport type SubscriptionSubscribeFunc = (\n  resolverData: SubscribeResolverData<any, any, any>,\n) => MaybePromise<AsyncIterable<any>>;\n\nexport type SubscriptionTopicIdFunc = (resolverData: SubscribeResolverData<any, any, any>) => any;\n\nexport interface DecoratorTypeOptions {\n  nullable?: boolean | NullableListOptions;\n  defaultValue?: any;\n}\n\nexport type NullableListOptions = \"items\" | \"itemsAndList\";\n\nexport interface TypeOptions extends DecoratorTypeOptions {\n  array?: boolean;\n  arrayDepth?: number;\n}\nexport interface DescriptionOptions {\n  description?: string;\n}\nexport interface DeprecationOptions {\n  deprecationReason?: string;\n}\nexport interface ValidateOptions {\n  validate?: ValidateSettings;\n  validateFn?: ValidatorFn;\n}\nexport interface ComplexityOptions {\n  complexity?: Complexity;\n}\nexport interface SchemaNameOptions {\n  name?: string;\n}\nexport interface ImplementsClassOptions {\n  implements?: Function | Function[];\n}\nexport interface ResolveTypeOptions<TSource = any, TContext = any> {\n  resolveType?: TypeResolver<TSource, TContext>;\n}\nexport type BasicOptions = DecoratorTypeOptions & DescriptionOptions;\nexport type AdvancedOptions = BasicOptions &\n  DeprecationOptions &\n  SchemaNameOptions &\n  ComplexityOptions;\n\nexport interface EnumConfig<TEnum extends object> {\n  name: string;\n  description?: string;\n  valuesConfig?: EnumValuesConfig<TEnum>;\n}\nexport type EnumValuesConfig<TEnum extends object> = Partial<\n  Record<keyof TEnum, DescriptionOptions & DeprecationOptions>\n>;\n\nexport type MethodAndPropDecorator = PropertyDecorator & MethodDecorator;\n\nexport type MethodPropClassDecorator = PropertyDecorator & MethodDecorator & ClassDecorator;\n"
  },
  {
    "path": "src/decorators/unions.ts",
    "content": "import { type UnionFromClasses } from \"@/helpers/utils\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ClassType } from \"@/typings\";\nimport { type ResolveTypeOptions } from \"./types\";\n\nexport type UnionTypeConfig<TClassTypes extends readonly ClassType[]> = {\n  name: string;\n  description?: string;\n  types: () => TClassTypes;\n} & ResolveTypeOptions<UnionFromClasses<TClassTypes>>;\n\nexport function createUnionType<T extends readonly ClassType[]>(\n  config: UnionTypeConfig<T>,\n): UnionFromClasses<T>;\nexport function createUnionType({\n  name,\n  description,\n  types,\n  resolveType,\n}: UnionTypeConfig<ClassType[]>): any {\n  const unionMetadataSymbol = getMetadataStorage().collectUnionMetadata({\n    name,\n    description,\n    getClassTypes: types,\n    resolveType,\n  });\n  return unionMetadataSymbol;\n}\n"
  },
  {
    "path": "src/errors/CannotDetermineGraphQLTypeError.ts",
    "content": "export class CannotDetermineGraphQLTypeError extends Error {\n  constructor(\n    typeKind: \"input\" | \"output\",\n    typeName: string,\n    propertyKey: string,\n    parameterIndex?: number,\n    argName?: string,\n  ) {\n    let errorMessage = `Cannot determine GraphQL ${typeKind} type for `;\n    if (argName) {\n      errorMessage += `argument named '${argName}' of `;\n    } else if (parameterIndex !== undefined) {\n      errorMessage += `parameter #${parameterIndex} of `;\n    }\n    errorMessage +=\n      `'${propertyKey}' of '${typeName}' class. ` +\n      `Is the value, that is used as its TS type or explicit type, decorated with a proper ` +\n      `decorator or is it a proper ${typeKind} value?`;\n\n    super(errorMessage);\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/ConflictingDefaultValuesError.ts",
    "content": "export class ConflictingDefaultValuesError extends Error {\n  constructor(\n    typeName: string,\n    fieldName: string,\n    defaultValueFromDecorator: unknown,\n    defaultValueFromInitializer: unknown,\n  ) {\n    super(\n      `The '${fieldName}' field of '${typeName}' has conflicting default values. ` +\n        `Default value from decorator ('${defaultValueFromDecorator}') ` +\n        `is not equal to the property initializer value ('${defaultValueFromInitializer}').`,\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/GeneratingSchemaError.ts",
    "content": "import { type GraphQLError } from \"graphql\";\n\nexport class GeneratingSchemaError extends Error {\n  details: readonly GraphQLError[];\n\n  constructor(details: readonly GraphQLError[]) {\n    let errorMessage = \"Some errors occurred while generating GraphQL schema:\\n\";\n    errorMessage += details.map(it => `  ${it.message}\\n`);\n    errorMessage += \"Please check the `details` property of the error to get more detailed info.\";\n\n    super(errorMessage);\n    Object.setPrototypeOf(this, new.target.prototype);\n\n    this.details = details;\n  }\n}\n"
  },
  {
    "path": "src/errors/InterfaceResolveTypeError.ts",
    "content": "import { type ClassMetadata } from \"@/metadata/definitions\";\n\nexport class InterfaceResolveTypeError extends Error {\n  constructor(interfaceMetadata: ClassMetadata) {\n    super(\n      `Cannot resolve type for interface ${interfaceMetadata.name}! ` +\n        `You need to return instance of object type class, not a plain object!`,\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/InvalidDirectiveError.ts",
    "content": "export class InvalidDirectiveError extends Error {\n  constructor(msg: string) {\n    super(msg);\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/MissingPubSubError.ts",
    "content": "export class MissingPubSubError extends Error {\n  constructor() {\n    super(\n      \"Looks like you've forgot to provide `pubSub` option in `buildSchema()`. \" +\n        \"Subscriptions can't work without a proper PubSub system.\",\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/MissingSubscriptionTopicsError.ts",
    "content": "export class MissingSubscriptionTopicsError extends Error {\n  constructor(target: Function, methodName: string) {\n    super(`${target.name}#${methodName} subscription has no provided topics!`);\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/NoExplicitTypeError.ts",
    "content": "export class NoExplicitTypeError extends Error {\n  constructor(typeName: string, propertyKey: string, parameterIndex?: number, argName?: string) {\n    let errorMessage =\n      `Unable to infer GraphQL type from TypeScript reflection system. ` +\n      `You need to provide explicit type for `;\n    if (argName) {\n      errorMessage += `argument named '${argName}' of `;\n    } else if (parameterIndex !== undefined) {\n      errorMessage += `parameter #${parameterIndex} of `;\n    }\n    errorMessage += `'${propertyKey}' of '${typeName}' class.`;\n    super(errorMessage);\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/ReflectMetadataMissingError.ts",
    "content": "export class ReflectMetadataMissingError extends Error {\n  constructor() {\n    super(\n      \"Looks like you've forgot to provide experimental metadata API polyfill. \" +\n        \"Please read the installation instruction for more details.\",\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/SymbolKeysNotSupportedError.ts",
    "content": "export class SymbolKeysNotSupportedError extends Error {\n  constructor() {\n    super(\"Symbol keys are not supported yet!\");\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/UnionResolveTypeError.ts",
    "content": "import { type UnionMetadata } from \"@/metadata/definitions\";\n\nexport class UnionResolveTypeError extends Error {\n  constructor(unionMetadata: UnionMetadata) {\n    super(\n      `Cannot resolve type for union ${unionMetadata.name}! ` +\n        `You need to return instance of object type class, not a plain object!`,\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/UnmetGraphQLPeerDependencyError.ts",
    "content": "export class UnmetGraphQLPeerDependencyError extends Error {\n  constructor(graphQLVersion: string, graphQLPeerDependencyVersion: string) {\n    super(\n      `Looks like you use an incorrect version of the 'graphql' package: \"${graphQLVersion}\". ` +\n        `Please ensure that you have installed a version ` +\n        `that meets TypeGraphQL's requirement: \"${graphQLPeerDependencyVersion}\".`,\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/WrongNullableListOptionError.ts",
    "content": "import { type NullableListOptions } from \"@/decorators/types\";\n\nexport class WrongNullableListOptionError extends Error {\n  constructor(\n    targetName: string,\n    propertyName: string,\n    nullable: boolean | NullableListOptions | undefined,\n  ) {\n    super(\n      `Wrong nullable option set for ${targetName}#${propertyName}. ` +\n        `You cannot combine non-list type with nullable '${nullable}'.`,\n    );\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/graphql/ArgumentValidationError.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore `class-validator` might not be installed by user\nimport { type ValidationError } from \"class-validator\";\nimport { GraphQLError } from \"graphql\";\n\nexport class ArgumentValidationError extends GraphQLError {\n  override readonly extensions!: {\n    code: \"BAD_USER_INPUT\";\n    validationErrors: ValidationError[];\n    [attributeName: string]: unknown; // GraphQLErrorExtensions\n  };\n\n  constructor(validationErrors: ValidationError[]) {\n    super(\"Argument Validation Error\", {\n      extensions: {\n        code: \"BAD_USER_INPUT\",\n        validationErrors,\n      },\n    });\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/graphql/AuthenticationError.ts",
    "content": "import { GraphQLError } from \"graphql\";\n\nexport class AuthenticationError extends GraphQLError {\n  override readonly extensions!: {\n    code: \"UNAUTHENTICATED\";\n    [attributeName: string]: unknown; // GraphQLErrorExtensions\n  };\n\n  constructor(message = \"Access denied! You need to be authenticated to perform this action!\") {\n    super(message, {\n      extensions: {\n        code: \"UNAUTHENTICATED\",\n      },\n    });\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/graphql/AuthorizationError.ts",
    "content": "import { GraphQLError } from \"graphql\";\n\nexport class AuthorizationError extends GraphQLError {\n  override readonly extensions!: {\n    code: \"UNAUTHORIZED\";\n    [attributeName: string]: unknown; // GraphQLErrorExtensions\n  };\n\n  constructor(message = \"Access denied! You don't have permission for this action!\") {\n    super(message, {\n      extensions: {\n        code: \"UNAUTHORIZED\",\n      },\n    });\n\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n"
  },
  {
    "path": "src/errors/graphql/index.ts",
    "content": "export * from \"./AuthenticationError\";\nexport * from \"./AuthorizationError\";\nexport * from \"./ArgumentValidationError\";\n"
  },
  {
    "path": "src/errors/index.ts",
    "content": "export * from \"./graphql\";\nexport * from \"./CannotDetermineGraphQLTypeError\";\nexport * from \"./GeneratingSchemaError\";\nexport * from \"./ConflictingDefaultValuesError\";\nexport * from \"./InterfaceResolveTypeError\";\nexport * from \"./InvalidDirectiveError\";\nexport * from \"./MissingPubSubError\";\nexport * from \"./MissingSubscriptionTopicsError\";\nexport * from \"./NoExplicitTypeError\";\nexport * from \"./ReflectMetadataMissingError\";\nexport * from \"./SymbolKeysNotSupportedError\";\nexport * from \"./UnionResolveTypeError\";\nexport * from \"./UnmetGraphQLPeerDependencyError\";\nexport * from \"./WrongNullableListOptionError\";\n"
  },
  {
    "path": "src/helpers/auth-middleware.ts",
    "content": "import { AuthenticationError, AuthorizationError } from \"@/errors\";\nimport { type AuthChecker, type AuthCheckerFn, type AuthMode } from \"@/typings\";\nimport { type MiddlewareFn } from \"@/typings/middleware\";\nimport { type IOCContainer } from \"@/utils/container\";\n\nexport function AuthMiddleware(\n  authChecker: AuthChecker<any, any>,\n  container: IOCContainer,\n  authMode: AuthMode,\n  roles: any[],\n): MiddlewareFn {\n  return async (action, next) => {\n    let accessGranted: boolean;\n    if (authChecker.prototype) {\n      const authCheckerInstance = await container.getInstance(authChecker, action);\n      accessGranted = await authCheckerInstance.check(action, roles);\n    } else {\n      accessGranted = await (authChecker as AuthCheckerFn<any, any>)(action, roles);\n    }\n\n    if (!accessGranted) {\n      if (authMode === \"null\") {\n        return null;\n      }\n      if (authMode === \"error\") {\n        throw roles.length === 0 ? new AuthenticationError() : new AuthorizationError();\n      }\n    }\n    return next();\n  };\n}\n"
  },
  {
    "path": "src/helpers/decorators.ts",
    "content": "import { type DescriptionOptions, type ReturnTypeFunc } from \"@/decorators/types\";\n\nexport interface TypeDecoratorParams<T> {\n  options: Partial<T>;\n  returnTypeFunc?: ReturnTypeFunc;\n}\nexport function getTypeDecoratorParams<T extends object>(\n  returnTypeFuncOrOptions: ReturnTypeFunc | T | undefined,\n  maybeOptions: T | undefined,\n): TypeDecoratorParams<T> {\n  if (typeof returnTypeFuncOrOptions === \"function\") {\n    return {\n      returnTypeFunc: returnTypeFuncOrOptions as ReturnTypeFunc,\n      options: maybeOptions || {},\n    };\n  }\n  return {\n    options: returnTypeFuncOrOptions || {},\n  };\n}\n\nexport function getNameDecoratorParams<T extends DescriptionOptions>(\n  nameOrOptions: string | T | undefined,\n  maybeOptions: T | undefined,\n) {\n  if (typeof nameOrOptions === \"string\") {\n    return {\n      name: nameOrOptions,\n      options: maybeOptions || ({} as T),\n    };\n  }\n  return {\n    options: nameOrOptions || ({} as T),\n  };\n}\n\nexport function getArrayFromOverloadedRest<T>(overloadedArray: Array<T | readonly T[]>): T[] {\n  let items: T[];\n  if (Array.isArray(overloadedArray[0])) {\n    items = overloadedArray[0] as T[];\n  } else {\n    items = overloadedArray as T[];\n  }\n  return items;\n}\n"
  },
  {
    "path": "src/helpers/filesystem.ts",
    "content": "import fs from \"node:fs\";\nimport asyncFs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport async function outputFile(filePath: string, fileContent: any) {\n  try {\n    await asyncFs.writeFile(filePath, fileContent);\n  } catch (err) {\n    if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n      throw err;\n    }\n    await asyncFs.mkdir(path.dirname(filePath), { recursive: true });\n    await asyncFs.writeFile(filePath, fileContent);\n  }\n}\n\nexport function outputFileSync(filePath: string, fileContent: any) {\n  try {\n    fs.writeFileSync(filePath, fileContent);\n  } catch (err) {\n    if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n      throw err;\n    }\n    fs.mkdirSync(path.dirname(filePath), { recursive: true });\n    fs.writeFileSync(filePath, fileContent);\n  }\n}\n"
  },
  {
    "path": "src/helpers/findType.ts",
    "content": "import {\n  type RecursiveArray,\n  type ReturnTypeFunc,\n  type TypeOptions,\n  type TypeValue,\n  type TypeValueThunk,\n} from \"@/decorators/types\";\nimport { NoExplicitTypeError } from \"@/errors\";\nimport { ensureReflectMetadataExists } from \"@/metadata/utils\";\nimport { bannedTypes } from \"./returnTypes\";\n\nexport type MetadataKey = \"design:type\" | \"design:returntype\" | \"design:paramtypes\";\n\nexport interface TypeInfo {\n  getType: TypeValueThunk;\n  typeOptions: TypeOptions;\n}\n\nexport interface GetTypeParams {\n  metadataKey: MetadataKey;\n  prototype: Object;\n  propertyKey: string;\n  parameterIndex?: number;\n  argName?: string;\n  returnTypeFunc?: ReturnTypeFunc;\n  typeOptions?: TypeOptions;\n}\n\nfunction findTypeValueArrayDepth(\n  [typeValueOrArray]: RecursiveArray<TypeValue>,\n  innerDepth = 1,\n): { depth: number; returnType: TypeValue } {\n  if (!Array.isArray(typeValueOrArray)) {\n    return { depth: innerDepth, returnType: typeValueOrArray };\n  }\n  return findTypeValueArrayDepth(typeValueOrArray, innerDepth + 1);\n}\n\nexport function findType({\n  metadataKey,\n  prototype,\n  propertyKey,\n  parameterIndex,\n  argName,\n  returnTypeFunc,\n  typeOptions = {},\n}: GetTypeParams): TypeInfo {\n  const options: TypeOptions = { ...typeOptions };\n  let metadataDesignType: Function | undefined;\n  ensureReflectMetadataExists();\n  const reflectedType: Function[] | Function | undefined = Reflect.getMetadata(\n    metadataKey,\n    prototype,\n    propertyKey,\n  );\n  if (reflectedType) {\n    if (metadataKey === \"design:paramtypes\") {\n      metadataDesignType = (reflectedType as Function[])[parameterIndex!];\n    } else {\n      metadataDesignType = reflectedType as Function;\n    }\n  }\n\n  if (!returnTypeFunc && (!metadataDesignType || bannedTypes.includes(metadataDesignType))) {\n    throw new NoExplicitTypeError(prototype.constructor.name, propertyKey, parameterIndex, argName);\n  }\n\n  if (returnTypeFunc) {\n    const getType = () => {\n      const returnTypeFuncReturnValue = returnTypeFunc();\n      if (Array.isArray(returnTypeFuncReturnValue)) {\n        const { depth, returnType } = findTypeValueArrayDepth(returnTypeFuncReturnValue);\n        options.array = true;\n        options.arrayDepth = depth;\n        return returnType;\n      }\n      return returnTypeFuncReturnValue;\n    };\n    return {\n      getType,\n      typeOptions: options,\n    };\n  }\n  if (metadataDesignType) {\n    return {\n      getType: () => metadataDesignType!,\n      typeOptions: options,\n    };\n  }\n  throw new Error(\"Ops... this should never happen :)\");\n}\n"
  },
  {
    "path": "src/helpers/isThrowing.ts",
    "content": "export function isThrowing(fn: () => void) {\n  try {\n    fn();\n    return false;\n  } catch {\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/helpers/params.ts",
    "content": "import { type ReturnTypeFunc, type TypeOptions, type ValidateOptions } from \"@/decorators/types\";\nimport { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { type CommonArgMetadata } from \"@/metadata/definitions\";\nimport { findType } from \"./findType\";\n\nexport interface ParamInfo {\n  prototype: Object;\n  propertyKey: string | symbol;\n  parameterIndex: number;\n  argName?: string;\n  returnTypeFunc?: ReturnTypeFunc;\n  options?: TypeOptions & ValidateOptions;\n}\nexport function getParamInfo({\n  prototype,\n  propertyKey,\n  parameterIndex,\n  argName,\n  returnTypeFunc,\n  options = {},\n}: ParamInfo): CommonArgMetadata {\n  if (typeof propertyKey === \"symbol\") {\n    throw new SymbolKeysNotSupportedError();\n  }\n\n  const { getType, typeOptions } = findType({\n    metadataKey: \"design:paramtypes\",\n    prototype,\n    propertyKey,\n    parameterIndex,\n    argName,\n    returnTypeFunc,\n    typeOptions: options,\n  });\n\n  return {\n    target: prototype.constructor,\n    methodName: propertyKey,\n    index: parameterIndex,\n    getType,\n    typeOptions,\n    validateSettings: options.validate,\n    validateFn: options.validateFn,\n  };\n}\n"
  },
  {
    "path": "src/helpers/resolver-metadata.ts",
    "content": "import { type AdvancedOptions, type ReturnTypeFunc } from \"@/decorators/types\";\nimport { SymbolKeysNotSupportedError } from \"@/errors\";\nimport { type ResolverMetadata } from \"@/metadata/definitions\";\nimport { findType } from \"./findType\";\n\nexport function getResolverMetadata(\n  prototype: object,\n  propertyKey: string | symbol,\n  returnTypeFunc?: ReturnTypeFunc,\n  options: AdvancedOptions = {},\n): ResolverMetadata {\n  if (typeof propertyKey === \"symbol\") {\n    throw new SymbolKeysNotSupportedError();\n  }\n\n  const { getType, typeOptions } = findType({\n    metadataKey: \"design:returntype\",\n    prototype,\n    propertyKey,\n    returnTypeFunc,\n    typeOptions: options,\n  });\n\n  const methodName = propertyKey as keyof typeof prototype;\n\n  return {\n    methodName,\n    schemaName: options.name || methodName,\n    target: prototype.constructor,\n    getReturnType: getType,\n    returnTypeOptions: typeOptions,\n    description: options.description,\n    deprecationReason: options.deprecationReason,\n    complexity: options.complexity,\n  };\n}\n"
  },
  {
    "path": "src/helpers/returnTypes.ts",
    "content": "export const allowedTypes: Function[] = [String, Number, Date, Boolean];\nexport const bannedTypes: Function[] = [Promise, Array, Object, Function];\n"
  },
  {
    "path": "src/helpers/types.ts",
    "content": "import {\n  GraphQLBoolean,\n  GraphQLFloat,\n  GraphQLList,\n  GraphQLNonNull,\n  GraphQLScalarType,\n  GraphQLString,\n  type GraphQLType,\n} from \"graphql\";\nimport { type TypeOptions } from \"@/decorators/types\";\nimport { WrongNullableListOptionError } from \"@/errors\";\nimport { GraphQLISODateTime } from \"@/scalars\";\nimport { BuildContext } from \"@/schema/build-context\";\n\nfunction wrapTypeInNestedList(\n  targetType: GraphQLType,\n  depth: number,\n  nullable: boolean,\n): GraphQLList<GraphQLType> {\n  const targetTypeNonNull = nullable ? targetType : new GraphQLNonNull(targetType);\n\n  if (depth === 0) {\n    return targetType as GraphQLList<GraphQLType>;\n  }\n  return wrapTypeInNestedList(new GraphQLList(targetTypeNonNull), depth - 1, nullable);\n}\n\nexport function convertTypeIfScalar(type: any): GraphQLScalarType | undefined {\n  if (type instanceof GraphQLScalarType) {\n    return type;\n  }\n  const scalarMap = BuildContext.scalarsMaps.find(it => it.type === type);\n  if (scalarMap) {\n    return scalarMap.scalar;\n  }\n\n  switch (type) {\n    case String:\n      return GraphQLString;\n    case Boolean:\n      return GraphQLBoolean;\n    case Number:\n      return GraphQLFloat;\n    case Date:\n      return GraphQLISODateTime;\n    default:\n      return undefined;\n  }\n}\n\nexport function wrapWithTypeOptions<T extends GraphQLType>(\n  target: Function,\n  propertyName: string,\n  type: T,\n  typeOptions: TypeOptions,\n  nullableByDefault: boolean,\n): T {\n  if (\n    !typeOptions.array &&\n    (typeOptions.nullable === \"items\" || typeOptions.nullable === \"itemsAndList\")\n  ) {\n    throw new WrongNullableListOptionError(target.name, propertyName, typeOptions.nullable);\n  }\n\n  let gqlType: GraphQLType = type;\n\n  if (typeOptions.array) {\n    const isNullableArray =\n      typeOptions.nullable === \"items\" ||\n      typeOptions.nullable === \"itemsAndList\" ||\n      (typeOptions.nullable === undefined && nullableByDefault === true);\n    gqlType = wrapTypeInNestedList(gqlType, typeOptions.arrayDepth!, isNullableArray);\n  }\n\n  if (\n    typeOptions.nullable === false ||\n    (typeOptions.nullable === undefined && nullableByDefault === false) ||\n    typeOptions.nullable === \"items\"\n  ) {\n    gqlType = new GraphQLNonNull(gqlType);\n  }\n\n  return gqlType as T;\n}\n\nconst simpleTypes: Function[] = [String, Boolean, Number, Date, Array, Promise];\nexport function convertToType(Target: any, data?: object): object | undefined {\n  // skip converting undefined and null\n  if (data == null) {\n    return data;\n  }\n  // skip converting scalars (object scalar mostly)\n  if (Target instanceof GraphQLScalarType) {\n    return data;\n  }\n  // skip converting simple types\n  if (simpleTypes.includes(data.constructor)) {\n    return data;\n  }\n  // skip converting already converted types\n  if (data instanceof Target) {\n    return data;\n  }\n  // convert array to instances\n  if (Array.isArray(data)) {\n    return data.map(item => convertToType(Target, item));\n  }\n\n  // Create instance by calling constructor to initialize instance fields\n  const instance = new (Target as any)();\n\n  // Remove undefined properties that weren't provided in the input data\n  // This prevents optional @Field() decorated properties from being enumerable\n  for (const key of Object.keys(instance)) {\n    if (instance[key] === undefined && !(key in data)) {\n      delete instance[key];\n    }\n  }\n\n  return Object.assign(instance, data);\n}\n\nexport function getEnumValuesMap<T extends object>(enumObject: T) {\n  const enumKeys = Object.keys(enumObject).filter(key => Number.isNaN(parseInt(key, 10)));\n  const enumMap = enumKeys.reduce<any>((map, key) => {\n    // eslint-disable-next-line no-param-reassign\n    map[key] = enumObject[key as keyof T];\n    return map;\n  }, {});\n  return enumMap;\n}\n"
  },
  {
    "path": "src/helpers/utils.ts",
    "content": "export type ArrayElements<TArray extends readonly any[]> =\n  TArray extends ReadonlyArray<infer TElement> ? TElement : never;\n\nexport type UnionFromClasses<TClassesArray extends readonly any[]> = InstanceType<\n  ArrayElements<TClassesArray>\n>;\n"
  },
  {
    "path": "src/index.ts",
    "content": "export * from \"./decorators\";\nexport * from \"./errors\";\nexport * from \"./typings\";\nexport * from \"./metadata\";\nexport * from \"./scalars\";\nexport * from \"./utils\";\n"
  },
  {
    "path": "src/metadata/definitions/authorized-metadata.ts",
    "content": "export interface AuthorizedMetadata {\n  target: Function;\n  fieldName: string;\n  roles: any[];\n}\n\nexport type AuthorizedClassMetadata = Omit<AuthorizedMetadata, \"fieldName\">;\n"
  },
  {
    "path": "src/metadata/definitions/class-metadata.ts",
    "content": "import { type DirectiveMetadata } from \"./directive-metadata\";\nimport { type ExtensionsMetadata } from \"./extensions-metadata\";\nimport { type FieldMetadata } from \"./field-metadata\";\n\nexport interface ClassMetadata {\n  name: string;\n  target: Function;\n  fields?: FieldMetadata[];\n  description?: string;\n  directives?: DirectiveMetadata[];\n  extensions?: ExtensionsMetadata;\n  simpleResolvers?: boolean;\n}\n"
  },
  {
    "path": "src/metadata/definitions/directive-metadata.ts",
    "content": "export interface DirectiveMetadata {\n  nameOrDefinition: string;\n  args: Record<string, any>;\n}\n\nexport interface DirectiveClassMetadata {\n  target: Function;\n  directive: DirectiveMetadata;\n}\n\nexport interface DirectiveFieldMetadata {\n  target: Function;\n  fieldName: string;\n  directive: DirectiveMetadata;\n}\n\nexport interface DirectiveArgumentMetadata {\n  target: Function;\n  fieldName: string;\n  parameterIndex: number;\n  directive: DirectiveMetadata;\n}\n"
  },
  {
    "path": "src/metadata/definitions/enum-metadata.ts",
    "content": "import { type EnumValuesConfig } from \"@/decorators/types\";\n\nexport interface EnumMetadata {\n  enumObj: object;\n  name: string;\n  description: string | undefined;\n  valuesConfig: EnumValuesConfig<any>;\n}\n"
  },
  {
    "path": "src/metadata/definitions/extensions-metadata.ts",
    "content": "export type ExtensionsMetadata = Readonly<Record<string, any>>;\n\nexport interface ExtensionsClassMetadata {\n  target: Function;\n  extensions: ExtensionsMetadata;\n}\n\nexport interface ExtensionsFieldMetadata {\n  target: Function;\n  fieldName: string;\n  extensions: ExtensionsMetadata;\n}\n"
  },
  {
    "path": "src/metadata/definitions/field-metadata.ts",
    "content": "import { type TypeOptions, type TypeValueThunk } from \"@/decorators/types\";\nimport { type Complexity } from \"@/typings\";\nimport { type Middleware } from \"@/typings/middleware\";\nimport { type DirectiveMetadata } from \"./directive-metadata\";\nimport { type ExtensionsMetadata } from \"./extensions-metadata\";\nimport { type ParamMetadata } from \"./param-metadata\";\n\nexport interface FieldMetadata {\n  target: Function;\n  schemaName: string;\n  name: string;\n  getType: TypeValueThunk;\n  typeOptions: TypeOptions;\n  description: string | undefined;\n  deprecationReason: string | undefined;\n  complexity: Complexity | undefined;\n  params?: ParamMetadata[];\n  roles?: any[];\n  middlewares?: Array<Middleware<any>>;\n  directives?: DirectiveMetadata[];\n  extensions?: ExtensionsMetadata;\n  simple?: boolean;\n}\n"
  },
  {
    "path": "src/metadata/definitions/index.ts",
    "content": "export * from \"./authorized-metadata\";\nexport * from \"./class-metadata\";\nexport * from \"./directive-metadata\";\nexport * from \"./enum-metadata\";\nexport * from \"./extensions-metadata\";\nexport * from \"./field-metadata\";\nexport * from \"./middleware-metadata\";\nexport * from \"./param-metadata\";\nexport * from \"./resolver-metadata\";\nexport * from \"./union-metadata\";\n"
  },
  {
    "path": "src/metadata/definitions/interface-class-metadata.ts",
    "content": "import { type TypeResolver } from \"@/typings\";\nimport { type ClassMetadata } from \"./class-metadata\";\n\nexport type InterfaceClassMetadata = {\n  resolveType?: TypeResolver<any, any>;\n  autoRegisteringDisabled: boolean;\n  interfaceClasses: Function[] | undefined;\n} & ClassMetadata;\n"
  },
  {
    "path": "src/metadata/definitions/middleware-metadata.ts",
    "content": "import { type Middleware } from \"@/typings/middleware\";\n\nexport interface MiddlewareMetadata {\n  target: Function;\n  fieldName: string;\n  middlewares: Array<Middleware<any>>;\n}\n\nexport type ResolverMiddlewareMetadata = Omit<MiddlewareMetadata, \"fieldName\">;\n"
  },
  {
    "path": "src/metadata/definitions/object-class-metadata.ts",
    "content": "import { type ClassMetadata } from \"./class-metadata\";\n\nexport type ObjectClassMetadata = {\n  interfaceClasses: Function[] | undefined;\n} & ClassMetadata;\n"
  },
  {
    "path": "src/metadata/definitions/param-metadata.ts",
    "content": "import { type TypeOptions, type TypeValueThunk } from \"@/decorators/types\";\nimport { type ValidateSettings } from \"@/schema/build-context\";\nimport { type ResolverData, type ValidatorFn } from \"@/typings\";\n\nexport interface BasicParamMetadata {\n  target: Function;\n  methodName: string;\n  index: number;\n}\n\nexport type InfoParamMetadata = {\n  kind: \"info\";\n} & BasicParamMetadata;\n\nexport type PubSubParamMetadata = {\n  kind: \"pubSub\";\n  triggerKey?: string;\n} & BasicParamMetadata;\n\nexport type ContextParamMetadata = {\n  kind: \"context\";\n  propertyName: string | undefined;\n} & BasicParamMetadata;\n\nexport type RootParamMetadata = {\n  kind: \"root\";\n  propertyName: string | undefined;\n  getType: TypeValueThunk | undefined;\n} & BasicParamMetadata;\n\nexport type CommonArgMetadata = {\n  getType: TypeValueThunk;\n  typeOptions: TypeOptions;\n  validateSettings: ValidateSettings | undefined;\n  validateFn: ValidatorFn | undefined;\n} & BasicParamMetadata;\n\nexport type ArgParamMetadata = {\n  kind: \"arg\";\n  name: string;\n  description: string | undefined;\n  deprecationReason: string | undefined;\n} & CommonArgMetadata;\n\nexport type ArgsParamMetadata = {\n  kind: \"args\";\n} & CommonArgMetadata;\n\nexport interface CustomParamOptions {\n  arg?: ArgParamMetadata;\n}\n\nexport type CustomParamMetadata = {\n  kind: \"custom\";\n  resolver: (resolverData: ResolverData<any>) => any;\n  options: CustomParamOptions;\n} & BasicParamMetadata;\n\nexport type ParamMetadata =\n  | InfoParamMetadata\n  | PubSubParamMetadata\n  | ContextParamMetadata\n  | RootParamMetadata\n  | ArgParamMetadata\n  | ArgsParamMetadata\n  | CustomParamMetadata;\n"
  },
  {
    "path": "src/metadata/definitions/resolver-metadata.ts",
    "content": "import {\n  type ClassTypeResolver,\n  type SubscriptionFilterFunc,\n  type SubscriptionSubscribeFunc,\n  type SubscriptionTopicIdFunc,\n  type SubscriptionTopicsFunc,\n  type TypeOptions,\n  type TypeValueThunk,\n} from \"@/decorators/types\";\nimport { type Complexity } from \"@/typings\";\nimport { type Middleware } from \"@/typings/middleware\";\nimport { type DirectiveMetadata } from \"./directive-metadata\";\nimport { type ExtensionsMetadata } from \"./extensions-metadata\";\nimport { type ParamMetadata } from \"./param-metadata\";\n\nexport interface BaseResolverMetadata {\n  methodName: string;\n  schemaName: string;\n  target: Function;\n  complexity: Complexity | undefined;\n  resolverClassMetadata?: ResolverClassMetadata;\n  params?: ParamMetadata[];\n  roles?: any[];\n  middlewares?: Array<Middleware<any>>;\n  directives?: DirectiveMetadata[];\n  extensions?: ExtensionsMetadata;\n}\n\nexport type ResolverMetadata = {\n  getReturnType: TypeValueThunk;\n  returnTypeOptions: TypeOptions;\n  description?: string;\n  deprecationReason?: string;\n} & BaseResolverMetadata;\n\nexport type FieldResolverMetadata = {\n  kind: \"internal\" | \"external\";\n  description?: string;\n  deprecationReason?: string;\n  getType?: TypeValueThunk;\n  typeOptions?: TypeOptions;\n  getObjectType?: ClassTypeResolver;\n} & BaseResolverMetadata;\n\nexport type SubscriptionResolverMetadata = {\n  topics: string | string[] | SubscriptionTopicsFunc | undefined;\n  topicId: SubscriptionTopicIdFunc | undefined;\n  filter: SubscriptionFilterFunc | undefined;\n  subscribe: SubscriptionSubscribeFunc | undefined;\n} & ResolverMetadata;\n\nexport interface ResolverClassMetadata {\n  target: Function;\n  getObjectType: ClassTypeResolver;\n  superResolver?: ResolverClassMetadata;\n}\n"
  },
  {
    "path": "src/metadata/definitions/union-metadata.ts",
    "content": "import { type ClassType, type TypeResolver } from \"@/typings\";\n\nexport interface UnionMetadata {\n  getClassTypes: () => ClassType[];\n  name: string;\n  description?: string;\n  resolveType?: TypeResolver<any, any>;\n}\nexport type UnionMetadataWithSymbol = {\n  symbol: symbol;\n} & UnionMetadata;\n"
  },
  {
    "path": "src/metadata/getMetadataStorage.ts",
    "content": "import { MetadataStorage } from \"./metadata-storage\";\n\ndeclare global {\n  // eslint-disable-next-line vars-on-top, no-var\n  var TypeGraphQLMetadataStorage: MetadataStorage;\n}\n\nexport function getMetadataStorage(): MetadataStorage {\n  if (!global.TypeGraphQLMetadataStorage) {\n    global.TypeGraphQLMetadataStorage = new MetadataStorage();\n  }\n\n  return global.TypeGraphQLMetadataStorage;\n}\n"
  },
  {
    "path": "src/metadata/index.ts",
    "content": "export { getMetadataStorage } from \"./getMetadataStorage\";\n"
  },
  {
    "path": "src/metadata/metadata-storage.ts",
    "content": "/* eslint-disable no-param-reassign */\nimport { NoExplicitTypeError } from \"@/errors\";\nimport { type SchemaGeneratorOptions } from \"@/schema/schema-generator\";\nimport { type ClassType } from \"@/typings\";\nimport {\n  type AuthorizedClassMetadata,\n  type AuthorizedMetadata,\n  type BaseResolverMetadata,\n  type ClassMetadata,\n  type EnumMetadata,\n  type ExtensionsClassMetadata,\n  type ExtensionsFieldMetadata,\n  type ExtensionsMetadata,\n  type FieldMetadata,\n  type FieldResolverMetadata,\n  type MiddlewareMetadata,\n  type ParamMetadata,\n  type ResolverClassMetadata,\n  type ResolverMetadata,\n  type ResolverMiddlewareMetadata,\n  type SubscriptionResolverMetadata,\n  type UnionMetadata,\n  type UnionMetadataWithSymbol,\n} from \"./definitions\";\nimport {\n  type DirectiveArgumentMetadata,\n  type DirectiveClassMetadata,\n  type DirectiveFieldMetadata,\n} from \"./definitions/directive-metadata\";\nimport { type InterfaceClassMetadata } from \"./definitions/interface-class-metadata\";\nimport { type ObjectClassMetadata } from \"./definitions/object-class-metadata\";\nimport {\n  mapMiddlewareMetadataToArray,\n  mapSuperFieldResolverHandlers,\n  mapSuperResolverHandlers,\n} from \"./utils\";\n\nexport class MetadataStorage {\n  queries: ResolverMetadata[] = [];\n\n  mutations: ResolverMetadata[] = [];\n\n  subscriptions: SubscriptionResolverMetadata[] = [];\n\n  fieldResolvers: FieldResolverMetadata[] = [];\n\n  objectTypes: ObjectClassMetadata[] = [];\n\n  objectTypesCache = new Map<Function, ObjectClassMetadata>();\n\n  inputTypes: ClassMetadata[] = [];\n\n  argumentTypes: ClassMetadata[] = [];\n\n  interfaceTypes: InterfaceClassMetadata[] = [];\n\n  interfaceTypesCache = new Map<Function, InterfaceClassMetadata>();\n\n  authorizedFields: AuthorizedMetadata[] = [];\n\n  authorizedFieldsByTargetAndFieldCache = new Map<Function, Map<string, AuthorizedMetadata>>();\n\n  authorizedResolver: AuthorizedClassMetadata[] = [];\n\n  authorizedResolverByTargetCache = new Map<Function, AuthorizedClassMetadata>();\n\n  enums: EnumMetadata[] = [];\n\n  unions: UnionMetadataWithSymbol[] = [];\n\n  middlewares: MiddlewareMetadata[] = [];\n\n  middlewaresByTargetAndFieldCache = new Map<Function, Map<string, Set<MiddlewareMetadata>>>();\n\n  resolverMiddlewares: ResolverMiddlewareMetadata[] = [];\n\n  resolverMiddlewaresByTargetCache = new Map<Function, Set<ResolverMiddlewareMetadata>>();\n\n  classDirectives: DirectiveClassMetadata[] = [];\n\n  classDirectivesByTargetCache = new Map<Function, DirectiveClassMetadata[]>();\n\n  fieldDirectives: DirectiveFieldMetadata[] = [];\n\n  fieldDirectivesByTargetAndFieldCache = new Map<Function, Map<string, DirectiveFieldMetadata[]>>();\n\n  argumentDirectives: DirectiveArgumentMetadata[] = [];\n\n  classExtensions: ExtensionsClassMetadata[] = [];\n\n  fieldExtensions: ExtensionsFieldMetadata[] = [];\n\n  resolverClasses: ResolverClassMetadata[] = [];\n\n  resolverClassesCache = new Map<Function, ResolverClassMetadata>();\n\n  fields: FieldMetadata[] = [];\n\n  fieldsCache = new Map<Function, FieldMetadata[]>();\n\n  params: ParamMetadata[] = [];\n\n  paramsCache = new Map<Function, Map<string, ParamMetadata[]>>();\n\n  collectQueryHandlerMetadata(definition: ResolverMetadata) {\n    this.queries.push(definition);\n  }\n\n  collectMutationHandlerMetadata(definition: ResolverMetadata) {\n    this.mutations.push(definition);\n  }\n\n  collectSubscriptionHandlerMetadata(definition: SubscriptionResolverMetadata) {\n    this.subscriptions.push(definition);\n  }\n\n  collectFieldResolverMetadata(definition: FieldResolverMetadata) {\n    this.fieldResolvers.push(definition);\n  }\n\n  collectObjectMetadata(definition: ObjectClassMetadata) {\n    this.objectTypes.push(definition);\n  }\n\n  collectInputMetadata(definition: ClassMetadata) {\n    this.inputTypes.push(definition);\n  }\n\n  collectArgsMetadata(definition: ClassMetadata) {\n    this.argumentTypes.push(definition);\n  }\n\n  collectInterfaceMetadata(definition: InterfaceClassMetadata) {\n    this.interfaceTypes.push(definition);\n  }\n\n  collectAuthorizedFieldMetadata(definition: AuthorizedMetadata) {\n    this.authorizedFields.push(definition);\n  }\n\n  collectAuthorizedResolverMetadata(definition: AuthorizedClassMetadata) {\n    this.authorizedResolver.push(definition);\n  }\n\n  collectEnumMetadata(definition: EnumMetadata) {\n    this.enums.push(definition);\n  }\n\n  collectUnionMetadata(definition: UnionMetadata) {\n    const unionSymbol = Symbol(definition.name);\n    this.unions.push({\n      ...definition,\n      symbol: unionSymbol,\n    });\n    return unionSymbol;\n  }\n\n  collectMiddlewareMetadata(definition: MiddlewareMetadata) {\n    this.middlewares.push(definition);\n  }\n\n  collectResolverMiddlewareMetadata(definition: ResolverMiddlewareMetadata) {\n    this.resolverMiddlewares.push(definition);\n  }\n\n  collectResolverClassMetadata(definition: ResolverClassMetadata) {\n    this.resolverClasses.push(definition);\n  }\n\n  collectClassFieldMetadata(definition: FieldMetadata) {\n    this.fields.push(definition);\n  }\n\n  collectHandlerParamMetadata(definition: ParamMetadata) {\n    this.params.push(definition);\n  }\n\n  collectDirectiveClassMetadata(definition: DirectiveClassMetadata) {\n    this.classDirectives.push(definition);\n  }\n\n  collectDirectiveFieldMetadata(definition: DirectiveFieldMetadata) {\n    this.fieldDirectives.push(definition);\n  }\n\n  collectDirectiveArgumentMetadata(definition: DirectiveArgumentMetadata) {\n    this.argumentDirectives.push(definition);\n  }\n\n  collectExtensionsClassMetadata(definition: ExtensionsClassMetadata) {\n    this.classExtensions.push(definition);\n  }\n\n  collectExtensionsFieldMetadata(definition: ExtensionsFieldMetadata) {\n    this.fieldExtensions.push(definition);\n  }\n\n  initCache() {\n    this.clearMapCaches();\n\n    if (this.resolverClasses?.length) {\n      this.resolverClasses.forEach(resolverClass => {\n        if (!this.resolverClassesCache.has(resolverClass.target)) {\n          this.resolverClassesCache.set(resolverClass.target, resolverClass);\n        }\n      });\n    }\n\n    if (this.params?.length) {\n      this.params.forEach(param => {\n        if (!this.paramsCache.has(param.target)) {\n          this.paramsCache.set(param.target, new Map());\n        }\n        if (!this.paramsCache.get(param.target)!.has(param.methodName)) {\n          this.paramsCache.get(param.target)!.set(param.methodName, []);\n        }\n        this.paramsCache.get(param.target)!.get(param.methodName)!.push(param);\n      });\n    }\n\n    if (this.middlewares?.length) {\n      this.middlewares.forEach(middleware => {\n        if (!this.middlewaresByTargetAndFieldCache.has(middleware.target)) {\n          this.middlewaresByTargetAndFieldCache.set(middleware.target, new Map());\n        }\n\n        if (\n          !this.middlewaresByTargetAndFieldCache.get(middleware.target)!.has(middleware.fieldName)\n        ) {\n          this.middlewaresByTargetAndFieldCache\n            .get(middleware.target)!\n            .set(middleware.fieldName, new Set());\n        }\n\n        if (\n          !this.middlewaresByTargetAndFieldCache\n            .get(middleware.target)!\n            .get(middleware.fieldName)!\n            .has(middleware)\n        ) {\n          this.middlewaresByTargetAndFieldCache\n            .get(middleware.target)!\n            .get(middleware.fieldName)!\n            .add(middleware);\n        }\n      });\n    }\n\n    if (this.resolverMiddlewares?.length) {\n      this.resolverMiddlewares.forEach(middleware => {\n        const key = middleware.target;\n        if (!this.resolverMiddlewaresByTargetCache.has(key)) {\n          this.resolverMiddlewaresByTargetCache.set(key, new Set());\n        }\n\n        if (!this.resolverMiddlewaresByTargetCache.get(key)!.has(middleware)) {\n          this.resolverMiddlewaresByTargetCache.get(key)!.add(middleware);\n        }\n      });\n    }\n\n    if (this.fieldDirectives?.length) {\n      this.fieldDirectives.forEach(directive => {\n        if (!this.fieldDirectivesByTargetAndFieldCache.has(directive.target)) {\n          this.fieldDirectivesByTargetAndFieldCache.set(directive.target, new Map());\n        }\n        if (\n          !this.fieldDirectivesByTargetAndFieldCache.get(directive.target)!.has(directive.fieldName)\n        ) {\n          this.fieldDirectivesByTargetAndFieldCache\n            .get(directive.target)!\n            .set(directive.fieldName, []);\n        }\n        this.fieldDirectivesByTargetAndFieldCache\n          .get(directive.target)!\n          .get(directive.fieldName)!\n          .push(directive);\n      });\n    }\n\n    if (this.classDirectives?.length) {\n      this.classDirectives.forEach(directive => {\n        const key = directive.target;\n        if (!this.classDirectivesByTargetCache.has(key)) {\n          this.classDirectivesByTargetCache.set(key, []);\n        }\n        this.classDirectivesByTargetCache.get(key)!.push(directive);\n      });\n    }\n\n    if (this.authorizedFields?.length) {\n      this.authorizedFields.forEach(field => {\n        if (!this.authorizedFieldsByTargetAndFieldCache.has(field.target)) {\n          this.authorizedFieldsByTargetAndFieldCache.set(field.target, new Map());\n        }\n        if (!this.authorizedFieldsByTargetAndFieldCache.get(field.target)!.has(field.fieldName)) {\n          this.authorizedFieldsByTargetAndFieldCache.get(field.target)!.set(field.fieldName, field);\n        }\n      });\n    }\n\n    if (this.authorizedResolver?.length) {\n      this.authorizedResolver.forEach(resolver => {\n        const key = resolver.target;\n        if (!this.authorizedResolverByTargetCache.has(key)) {\n          this.authorizedResolverByTargetCache.set(key, resolver);\n        }\n      });\n    }\n\n    if (this.fields?.length) {\n      this.fields.forEach(field => {\n        if (!this.fieldsCache.has(field.target)) {\n          this.fieldsCache.set(field.target, []);\n        }\n        this.fieldsCache.get(field.target)!.push(field);\n      });\n    }\n\n    if (this.objectTypes?.length) {\n      this.objectTypes.forEach(objType => {\n        this.objectTypesCache.set(objType.target, objType);\n      });\n    }\n\n    if (this.interfaceTypes?.length) {\n      this.interfaceTypes.forEach(interfaceType => {\n        this.interfaceTypesCache.set(interfaceType.target, interfaceType);\n      });\n    }\n  }\n\n  build(options: SchemaGeneratorOptions) {\n    this.classDirectives.reverse();\n    this.fieldDirectives.reverse();\n    this.argumentDirectives.reverse();\n    this.classExtensions.reverse();\n    this.fieldExtensions.reverse();\n\n    this.initCache();\n\n    this.buildClassMetadata(this.objectTypes);\n    this.buildClassMetadata(this.inputTypes);\n    this.buildClassMetadata(this.argumentTypes);\n    this.buildClassMetadata(this.interfaceTypes);\n\n    this.buildFieldResolverMetadata(this.fieldResolvers, options);\n\n    this.buildResolversMetadata(this.queries);\n    this.buildResolversMetadata(this.mutations);\n    this.buildResolversMetadata(this.subscriptions);\n\n    this.buildExtendedResolversMetadata();\n  }\n\n  clear() {\n    this.queries = [];\n    this.mutations = [];\n    this.subscriptions = [];\n    this.fieldResolvers = [];\n    this.objectTypes = [];\n    this.inputTypes = [];\n    this.argumentTypes = [];\n    this.interfaceTypes = [];\n    this.authorizedFields = [];\n    this.authorizedResolver = [];\n    this.enums = [];\n    this.unions = [];\n    this.middlewares = [];\n    this.resolverMiddlewares = [];\n    this.classDirectives = [];\n    this.fieldDirectives = [];\n    this.argumentDirectives = [];\n    this.classExtensions = [];\n    this.fieldExtensions = [];\n    this.resolverClasses = [];\n    this.fields = [];\n    this.params = [];\n\n    this.clearMapCaches();\n  }\n\n  clone() {\n    const cloned = new MetadataStorage();\n\n    // arrays are cloned to prevent mutation of original metadata storage when building schema\n    cloned.queries = [...this.queries];\n    cloned.mutations = [...this.mutations];\n    cloned.subscriptions = [...this.subscriptions];\n    cloned.fieldResolvers = [...this.fieldResolvers];\n    cloned.objectTypes = [...this.objectTypes];\n    cloned.inputTypes = [...this.inputTypes];\n    cloned.argumentTypes = [...this.argumentTypes];\n    cloned.interfaceTypes = [...this.interfaceTypes];\n    cloned.authorizedFields = [...this.authorizedFields];\n    cloned.authorizedResolver = [...this.authorizedResolver];\n    cloned.enums = [...this.enums];\n    cloned.unions = [...this.unions];\n    cloned.middlewares = [...this.middlewares];\n    cloned.resolverMiddlewares = [...this.resolverMiddlewares];\n    cloned.classDirectives = [...this.classDirectives];\n    cloned.fieldDirectives = [...this.fieldDirectives];\n    cloned.argumentDirectives = [...this.argumentDirectives];\n    cloned.classExtensions = [...this.classExtensions];\n    cloned.fieldExtensions = [...this.fieldExtensions];\n    cloned.resolverClasses = [...this.resolverClasses];\n    cloned.fields = [...this.fields];\n    cloned.params = [...this.params];\n\n    return cloned;\n  }\n\n  private clearMapCaches() {\n    this.fieldsCache = new Map();\n    this.objectTypesCache = new Map();\n    this.interfaceTypesCache = new Map();\n    this.middlewaresByTargetAndFieldCache = new Map();\n    this.resolverMiddlewaresByTargetCache = new Map();\n    this.paramsCache = new Map();\n    this.fieldDirectivesByTargetAndFieldCache = new Map();\n    this.classDirectivesByTargetCache = new Map();\n    this.authorizedFieldsByTargetAndFieldCache = new Map();\n    this.authorizedResolverByTargetCache = new Map();\n    this.resolverClassesCache = new Map();\n  }\n\n  private buildClassMetadata(definitions: ClassMetadata[]) {\n    definitions.forEach(def => {\n      if (!def.fields) {\n        const fields = this.fieldsCache.get(def.target) || [];\n        fields.forEach(field => {\n          field.roles = this.findFieldRoles(field.target, field.name);\n          field.params = this.paramsCache.get(field.target)?.get(field.name) || [];\n          field.middlewares = [\n            ...mapMiddlewareMetadataToArray([\n              ...(this.resolverMiddlewaresByTargetCache.get(field.target) || []),\n            ]),\n            ...mapMiddlewareMetadataToArray([\n              ...(this.middlewaresByTargetAndFieldCache.get(field.target)?.get(field.name) || []),\n            ]),\n          ];\n          field.directives = (\n            this.fieldDirectivesByTargetAndFieldCache.get(field.target)?.get(field.name) || []\n          ).map(it => it.directive);\n          field.extensions = this.findExtensions(field.target, field.name);\n        });\n        def.fields = fields;\n      }\n      if (!def.directives) {\n        def.directives = (this.classDirectivesByTargetCache.get(def.target) || []).map(\n          it => it.directive,\n        );\n      }\n      if (!def.extensions) {\n        def.extensions = this.findExtensions(def.target);\n      }\n    });\n  }\n\n  private buildResolversMetadata(definitions: BaseResolverMetadata[]) {\n    definitions.forEach(def => {\n      def.resolverClassMetadata = this.resolverClassesCache.get(def.target);\n      def.params = this.paramsCache.get(def.target)?.get(def.methodName) || [];\n      def.roles = this.findFieldRoles(def.target, def.methodName);\n      def.middlewares = [\n        ...mapMiddlewareMetadataToArray([\n          ...(this.resolverMiddlewaresByTargetCache.get(def.target) || []),\n        ]),\n        ...mapMiddlewareMetadataToArray([\n          ...(this.middlewaresByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []),\n        ]),\n      ];\n\n      def.directives = (\n        this.fieldDirectivesByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []\n      ).map(it => it.directive);\n      def.extensions = this.findExtensions(def.target, def.methodName);\n    });\n  }\n\n  private buildFieldResolverMetadata(\n    definitions: FieldResolverMetadata[],\n    options: SchemaGeneratorOptions,\n  ) {\n    this.buildResolversMetadata(definitions);\n    definitions.forEach(def => {\n      def.roles = this.findFieldRoles(def.target, def.methodName);\n      def.directives = (\n        this.fieldDirectivesByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []\n      ).map(it => it.directive);\n      def.extensions = this.findExtensions(def.target, def.methodName);\n      def.getObjectType =\n        def.kind === \"external\"\n          ? this.resolverClassesCache.get(def.target)!.getObjectType\n          : () => def.target as ClassType;\n      if (def.kind === \"external\") {\n        const typeClass = this.resolverClassesCache.get(def.target)!.getObjectType!();\n        const typeMetadata =\n          this.objectTypesCache.get(typeClass) || this.interfaceTypesCache.get(typeClass);\n        if (!typeMetadata) {\n          throw new Error(\n            `Unable to find type metadata for input type or object type named '${typeClass.name}'`,\n          );\n        }\n\n        const typeField = typeMetadata.fields!.find(\n          fieldDef => fieldDef.schemaName === def.schemaName,\n        )!;\n        if (!typeField) {\n          const shouldCollectFieldMetadata =\n            !options.resolvers ||\n            options.resolvers.some(\n              resolverCls =>\n                resolverCls === def.target ||\n                Object.prototype.isPrototypeOf.call(def.target, resolverCls),\n            );\n          if (!def.getType || !def.typeOptions) {\n            throw new NoExplicitTypeError(def.target.name, def.methodName);\n          }\n          if (shouldCollectFieldMetadata) {\n            const fieldMetadata: FieldMetadata = {\n              name: def.methodName,\n              schemaName: def.schemaName,\n              getType: def.getType!,\n              target: typeClass,\n              typeOptions: def.typeOptions!,\n              deprecationReason: def.deprecationReason,\n              description: def.description,\n              complexity: def.complexity,\n              roles: def.roles!,\n              middlewares: def.middlewares!,\n              params: def.params!,\n              directives: def.directives,\n              extensions: def.extensions,\n            };\n            this.collectClassFieldMetadata(fieldMetadata);\n            typeMetadata.fields!.push(fieldMetadata);\n          }\n        } else {\n          typeField.complexity = def.complexity;\n          if (typeField.params!.length === 0) {\n            typeField.params = def.params!;\n          }\n          if (def.roles) {\n            typeField.roles = def.roles;\n          } else if (typeField.roles) {\n            def.roles = typeField.roles;\n          }\n        }\n      }\n    });\n  }\n\n  private buildExtendedResolversMetadata() {\n    this.resolverClasses.forEach(def => {\n      let superResolver = Object.getPrototypeOf(def.target);\n\n      // copy and modify metadata of resolver from parent resolver class\n      while (superResolver.prototype) {\n        const superResolverMetadata = this.resolverClassesCache.get(superResolver);\n        if (superResolverMetadata) {\n          this.queries = mapSuperResolverHandlers(this.queries, superResolver, def);\n          this.mutations = mapSuperResolverHandlers(this.mutations, superResolver, def);\n          this.subscriptions = mapSuperResolverHandlers(this.subscriptions, superResolver, def);\n          this.fieldResolvers = mapSuperFieldResolverHandlers(\n            this.fieldResolvers,\n            superResolver,\n            def,\n          );\n        }\n        superResolver = Object.getPrototypeOf(superResolver);\n      }\n    });\n  }\n\n  private findFieldRoles(target: Function, fieldName: string): any[] | undefined {\n    const authorizedField =\n      this.authorizedFieldsByTargetAndFieldCache.get(target)?.get(fieldName) ||\n      this.authorizedResolverByTargetCache.get(target);\n    if (!authorizedField) {\n      return undefined;\n    }\n    return authorizedField.roles;\n  }\n\n  private findExtensions(target: Function, fieldName?: string): ExtensionsMetadata {\n    const storedExtensions: Array<ExtensionsClassMetadata | ExtensionsFieldMetadata> = fieldName\n      ? this.fieldExtensions\n      : this.classExtensions;\n    return storedExtensions\n      .filter(\n        entry =>\n          (entry.target === target || Object.prototype.isPrototypeOf.call(entry.target, target)) &&\n          (!(\"fieldName\" in entry) || entry.fieldName === fieldName),\n      )\n      .reduce((extensions, entry) => ({ ...extensions, ...entry.extensions }), {});\n  }\n}\n"
  },
  {
    "path": "src/metadata/utils.ts",
    "content": "import { ReflectMetadataMissingError } from \"@/errors\";\nimport { isThrowing } from \"@/helpers/isThrowing\";\nimport { type Middleware } from \"@/typings/middleware\";\nimport {\n  type BaseResolverMetadata,\n  type FieldResolverMetadata,\n  type ResolverClassMetadata,\n  type ResolverMiddlewareMetadata,\n} from \"./definitions\";\n\nexport function mapSuperResolverHandlers<T extends BaseResolverMetadata>(\n  definitions: T[],\n  superResolver: Function,\n  resolverMetadata: ResolverClassMetadata,\n): T[] {\n  return definitions.map(metadata =>\n    metadata.target === superResolver\n      ? {\n          ...metadata,\n          target: resolverMetadata.target,\n          resolverClassMetadata: resolverMetadata,\n        }\n      : metadata,\n  );\n}\n\nexport function mapSuperFieldResolverHandlers(\n  definitions: FieldResolverMetadata[],\n  superResolver: Function,\n  resolverMetadata: ResolverClassMetadata,\n) {\n  const superMetadata = mapSuperResolverHandlers(definitions, superResolver, resolverMetadata);\n\n  return superMetadata.map(metadata =>\n    metadata.target === superResolver\n      ? {\n          ...metadata,\n          getObjectType: isThrowing(metadata.getObjectType!)\n            ? resolverMetadata.getObjectType\n            : metadata.getObjectType,\n        }\n      : metadata,\n  );\n}\n\nexport function mapMiddlewareMetadataToArray(\n  metadata: ResolverMiddlewareMetadata[],\n): Array<Middleware<any>> {\n  return metadata\n    .map(m => m.middlewares)\n    .reduce<\n      Array<Middleware<any>>\n    >((middlewares, resultArray) => resultArray.concat(middlewares), []);\n}\n\nexport function ensureReflectMetadataExists() {\n  if (typeof Reflect !== \"object\" || typeof Reflect.getMetadata !== \"function\") {\n    throw new ReflectMetadataMissingError();\n  }\n}\n"
  },
  {
    "path": "src/resolvers/convert-args.ts",
    "content": "import { type TypeValue } from \"@/decorators/types\";\nimport { convertToType } from \"@/helpers/types\";\nimport {\n  type ArgParamMetadata,\n  type ArgsParamMetadata,\n  type ClassMetadata,\n} from \"@/metadata/definitions\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ArgsDictionary, type ClassType } from \"@/typings\";\n\ninterface TransformationTreeField {\n  name: string;\n  target: TypeValue;\n  fields?: TransformationTree;\n}\n\ninterface TransformationTree {\n  target: TypeValue;\n  getFields: () => TransformationTreeField[];\n}\n\nconst generatedTrees = new Map<TypeValue, TransformationTree | null>();\n\nfunction getInputType(target: TypeValue): ClassMetadata | undefined {\n  return getMetadataStorage().inputTypes.find(t => t.target === target);\n}\n\nfunction getArgsType(target: TypeValue): ClassMetadata | undefined {\n  return getMetadataStorage().argumentTypes.find(t => t.target === target);\n}\n\nfunction generateInstanceTransformationTree(target: TypeValue): TransformationTree | null {\n  if (generatedTrees.has(target)) {\n    return generatedTrees.get(target)!;\n  }\n\n  const inputType = getInputType(target);\n  if (!inputType) {\n    generatedTrees.set(target, null);\n    return null;\n  }\n\n  function generateTransformationTree(metadata: ClassMetadata): TransformationTree {\n    let inputFields = metadata.fields!;\n    let superClass = Object.getPrototypeOf(metadata.target);\n    while (superClass.prototype !== undefined) {\n      const superInputType = getInputType(superClass);\n      if (superInputType) {\n        // support overwriting fields of extended types\n        const existingFieldNames = new Set(inputFields.map(field => field.name));\n        const superFields = superInputType.fields!.filter(\n          field => !existingFieldNames.has(field.name),\n        );\n        inputFields = [...inputFields, ...superFields];\n      }\n      superClass = Object.getPrototypeOf(superClass);\n    }\n\n    const transformationTree: TransformationTree = {\n      target: metadata.target,\n      getFields: () =>\n        inputFields.map<TransformationTreeField>(field => {\n          const fieldTarget = field.getType();\n          const fieldInputType = getInputType(fieldTarget);\n          return {\n            name: field.name,\n            target: fieldTarget,\n            fields:\n              fieldTarget === metadata.target\n                ? transformationTree\n                : fieldInputType && generateTransformationTree(fieldInputType),\n          };\n        }),\n    };\n\n    return transformationTree;\n  }\n\n  const generatedTransformationTree = generateTransformationTree(inputType);\n  generatedTrees.set(target, generatedTransformationTree);\n  return generatedTransformationTree;\n}\n\nfunction convertToInput(tree: TransformationTree, data: any): any {\n  if (data == null) {\n    // skip converting undefined and null\n    return data;\n  }\n  if (Array.isArray(data)) {\n    // recursively convert nested arrays\n    return data.map(it => convertToInput(tree, it));\n  }\n\n  const inputFields = tree.getFields().reduce<Record<string, any>>((fields, field) => {\n    const siblings = field.fields;\n    const value = data[field.name];\n    // don't create property for nullable field\n    if (value !== undefined) {\n      if (value === null || !siblings) {\n        // eslint-disable-next-line no-param-reassign\n        fields[field.name] = convertToType(field.target, value);\n      } else if (Array.isArray(value)) {\n        // eslint-disable-next-line no-param-reassign\n        fields[field.name] = value.map(itemValue => convertToInput(siblings, itemValue));\n      } else {\n        // eslint-disable-next-line no-param-reassign\n        fields[field.name] = convertToInput(siblings, value);\n      }\n    }\n    return fields;\n  }, {});\n\n  return convertToType(tree.target, inputFields);\n}\n\nfunction convertValueToInstance(target: TypeValue, value: any): any {\n  const transformationTree = generateInstanceTransformationTree(target);\n  return transformationTree\n    ? convertToInput(transformationTree, value)\n    : convertToType(target, value);\n}\n\nfunction convertValuesToInstances(target: TypeValue, value: any): any {\n  // skip converting undefined and null\n  if (value == null) {\n    return value;\n  }\n  if (Array.isArray(value)) {\n    // call function recursively to handle nested arrays case\n    return value.map(itemValue => convertValuesToInstances(target, itemValue));\n  }\n  return convertValueToInstance(target, value);\n}\n\nexport function convertArgsToInstance(argsMetadata: ArgsParamMetadata, args: ArgsDictionary) {\n  const ArgsClass = argsMetadata.getType() as ClassType;\n  const argsType = getArgsType(ArgsClass)!;\n\n  let argsFields = argsType.fields!;\n  let superClass = Object.getPrototypeOf(argsType.target);\n  while (superClass.prototype !== undefined) {\n    const superArgumentType = getArgsType(superClass);\n    if (superArgumentType) {\n      argsFields = [...argsFields, ...superArgumentType.fields!];\n    }\n    superClass = Object.getPrototypeOf(superClass);\n  }\n\n  const transformedFields = argsFields.reduce<Record<string, any>>((fields, field) => {\n    const fieldValue = args[field.name];\n    // don't create property for nullable field\n    if (fieldValue !== undefined) {\n      const fieldTarget = field.getType();\n      // eslint-disable-next-line no-param-reassign\n      fields[field.name] = convertValuesToInstances(fieldTarget, fieldValue);\n    }\n    return fields;\n  }, {});\n\n  return convertToType(ArgsClass, transformedFields);\n}\n\nexport function convertArgToInstance(argMetadata: ArgParamMetadata, args: ArgsDictionary) {\n  const argValue = args[argMetadata.name];\n  const argTarget = argMetadata.getType();\n  return convertValuesToInstances(argTarget, argValue);\n}\n"
  },
  {
    "path": "src/resolvers/create.ts",
    "content": "import { type GraphQLFieldResolver } from \"graphql\";\nimport { AuthMiddleware } from \"@/helpers/auth-middleware\";\nimport { convertToType } from \"@/helpers/types\";\nimport {\n  type BaseResolverMetadata,\n  type FieldMetadata,\n  type FieldResolverMetadata,\n} from \"@/metadata/definitions\";\nimport { BuildContext } from \"@/schema/build-context\";\nimport { type ResolverData } from \"@/typings\";\nimport { type IOCContainer } from \"@/utils/container\";\nimport { isPromiseLike } from \"@/utils/isPromiseLike\";\nimport { applyAuthChecker, applyMiddlewares, getParams } from \"./helpers\";\n\nexport function createHandlerResolver(\n  resolverMetadata: BaseResolverMetadata,\n): GraphQLFieldResolver<any, any, any> {\n  const {\n    validate: globalValidate,\n    validateFn,\n    authChecker,\n    authMode,\n    globalMiddlewares,\n    container,\n  } = BuildContext;\n  const middlewares = globalMiddlewares.concat(resolverMetadata.middlewares!);\n  applyAuthChecker(middlewares, authChecker, container, authMode, resolverMetadata.roles);\n\n  return (root, args, context, info) => {\n    const resolverData: ResolverData<any> = { root, args, context, info };\n    const targetInstanceOrPromise: Promise<any> | any = container.getInstance(\n      resolverMetadata.target,\n      resolverData,\n    );\n    if (isPromiseLike(targetInstanceOrPromise)) {\n      return targetInstanceOrPromise.then(targetInstance =>\n        applyMiddlewares(container, resolverData, middlewares, () => {\n          const params: Promise<any[]> | any[] = getParams(\n            resolverMetadata.params!,\n            resolverData,\n            globalValidate,\n            validateFn,\n          );\n          if (isPromiseLike(params)) {\n            return params.then(resolvedParams =>\n              // eslint-disable-next-line prefer-spread\n              targetInstance[resolverMetadata.methodName].apply(targetInstance, resolvedParams),\n            );\n          }\n          // eslint-disable-next-line prefer-spread\n          return targetInstance[resolverMetadata.methodName].apply(targetInstance, params);\n        }),\n      );\n    }\n    return applyMiddlewares(container, resolverData, middlewares, () => {\n      const params: Promise<any[]> | any[] = getParams(\n        resolverMetadata.params!,\n        resolverData,\n        globalValidate,\n        validateFn,\n      );\n      const targetInstance = targetInstanceOrPromise;\n      if (isPromiseLike(params)) {\n        return params.then(resolvedParams =>\n          // eslint-disable-next-line prefer-spread\n          targetInstance[resolverMetadata.methodName].apply(targetInstance, resolvedParams),\n        );\n      }\n      // eslint-disable-next-line prefer-spread\n      return targetInstance[resolverMetadata.methodName].apply(targetInstance, params);\n    });\n  };\n}\n\nexport function createAdvancedFieldResolver(\n  fieldResolverMetadata: FieldResolverMetadata,\n): GraphQLFieldResolver<any, any, any> {\n  if (fieldResolverMetadata.kind === \"external\") {\n    return createHandlerResolver(fieldResolverMetadata);\n  }\n\n  const targetType = fieldResolverMetadata.getObjectType!();\n  const {\n    validate: globalValidate,\n    validateFn,\n    authChecker,\n    authMode,\n    globalMiddlewares,\n    container,\n  } = BuildContext;\n  const middlewares = globalMiddlewares.concat(fieldResolverMetadata.middlewares!);\n  applyAuthChecker(middlewares, authChecker, container, authMode, fieldResolverMetadata.roles);\n\n  return (root, args, context, info) => {\n    const resolverData: ResolverData<any> = { root, args, context, info };\n    const targetInstance: any = convertToType(targetType, root);\n    return applyMiddlewares(container, resolverData, middlewares, () => {\n      const handlerOrGetterValue = targetInstance[fieldResolverMetadata.methodName];\n      if (typeof handlerOrGetterValue !== \"function\") {\n        // getter\n        return handlerOrGetterValue;\n      }\n      // method\n      const params: Promise<any[]> | any[] = getParams(\n        fieldResolverMetadata.params!,\n        resolverData,\n        globalValidate,\n        validateFn,\n      );\n      if (isPromiseLike(params)) {\n        return params.then(resolvedParams =>\n          handlerOrGetterValue.apply(targetInstance, resolvedParams),\n        );\n      }\n      return handlerOrGetterValue.apply(targetInstance, params);\n    });\n  };\n}\n\nexport function createBasicFieldResolver(\n  fieldMetadata: FieldMetadata,\n): GraphQLFieldResolver<any, any, any> {\n  const { authChecker, authMode, globalMiddlewares, container } = BuildContext;\n  const middlewares = globalMiddlewares.concat(fieldMetadata.middlewares!);\n  applyAuthChecker(middlewares, authChecker, container, authMode, fieldMetadata.roles);\n\n  return (root, args, context, info) => {\n    const resolverData: ResolverData<any> = { root, args, context, info };\n    return applyMiddlewares(container, resolverData, middlewares, () => root[fieldMetadata.name]);\n  };\n}\n\nexport function wrapResolverWithAuthChecker(\n  resolver: GraphQLFieldResolver<any, any>,\n  container: IOCContainer,\n  roles: any[] | undefined,\n): GraphQLFieldResolver<any, any> {\n  const { authChecker, authMode } = BuildContext;\n  if (!authChecker || !roles) {\n    return resolver;\n  }\n\n  return (root, args, context, info) => {\n    const resolverData: ResolverData<any> = { root, args, context, info };\n    return AuthMiddleware(\n      authChecker,\n      container,\n      authMode,\n      roles,\n    )(resolverData, async () => resolver(root, args, context, info));\n  };\n}\n"
  },
  {
    "path": "src/resolvers/helpers.ts",
    "content": "import { AuthMiddleware } from \"@/helpers/auth-middleware\";\nimport { convertToType } from \"@/helpers/types\";\nimport { type ParamMetadata } from \"@/metadata/definitions\";\nimport { type ValidateSettings } from \"@/schema/build-context\";\nimport { type AuthChecker, type AuthMode, type ResolverData, type ValidatorFn } from \"@/typings\";\nimport { type Middleware, type MiddlewareClass, type MiddlewareFn } from \"@/typings/middleware\";\nimport { type IOCContainer } from \"@/utils/container\";\nimport { isPromiseLike } from \"@/utils/isPromiseLike\";\nimport { convertArgToInstance, convertArgsToInstance } from \"./convert-args\";\nimport { validateArg } from \"./validate-arg\";\n\nexport function getParams(\n  params: ParamMetadata[],\n  resolverData: ResolverData<any>,\n  globalValidate: ValidateSettings,\n  globalValidateFn: ValidatorFn | undefined,\n): Promise<any[]> | any[] {\n  const paramValues = params\n    .sort((a, b) => a.index - b.index)\n    // eslint-disable-next-line array-callback-return, consistent-return\n    .map(paramInfo => {\n      switch (paramInfo.kind) {\n        case \"args\":\n          return validateArg(\n            convertArgsToInstance(paramInfo, resolverData.args),\n            paramInfo.getType(),\n            resolverData,\n            globalValidate,\n            paramInfo.validateSettings,\n            globalValidateFn,\n            paramInfo.validateFn,\n          );\n\n        case \"arg\":\n          return validateArg(\n            convertArgToInstance(paramInfo, resolverData.args),\n            paramInfo.getType(),\n            resolverData,\n            globalValidate,\n            paramInfo.validateSettings,\n            globalValidateFn,\n            paramInfo.validateFn,\n          );\n\n        case \"context\":\n          if (paramInfo.propertyName) {\n            return resolverData.context[paramInfo.propertyName];\n          }\n          return resolverData.context;\n\n        case \"root\": {\n          const rootValue = paramInfo.propertyName\n            ? resolverData.root[paramInfo.propertyName]\n            : resolverData.root;\n\n          if (!paramInfo.getType) {\n            return rootValue;\n          }\n          return convertToType(paramInfo.getType(), rootValue);\n        }\n\n        case \"info\":\n          return resolverData.info;\n\n        case \"custom\":\n          if (paramInfo.options.arg) {\n            const arg = paramInfo.options.arg!;\n            return validateArg(\n              convertArgToInstance(arg, resolverData.args),\n              arg.getType(),\n              resolverData,\n              globalValidate,\n              arg.validateSettings,\n              globalValidateFn,\n              arg.validateFn,\n            ).then(() => paramInfo.resolver(resolverData));\n          }\n          return paramInfo.resolver(resolverData);\n\n        // no default\n      }\n    });\n\n  if (paramValues.some(isPromiseLike)) {\n    return Promise.all(paramValues);\n  }\n  return paramValues;\n}\n\nexport function applyAuthChecker(\n  middlewares: Array<Middleware<any>>,\n  authChecker: AuthChecker<any, any> | undefined,\n  container: IOCContainer,\n  authMode: AuthMode,\n  roles: any[] | undefined,\n) {\n  if (authChecker && roles) {\n    middlewares.unshift(AuthMiddleware(authChecker, container, authMode, roles));\n  }\n}\n\nexport function applyMiddlewares(\n  container: IOCContainer,\n  resolverData: ResolverData<any>,\n  middlewares: Array<Middleware<any>>,\n  resolverHandlerFunction: () => any,\n): Promise<any> {\n  if (middlewares.length === 0) {\n    return resolverHandlerFunction();\n  }\n  let middlewaresIndex = -1;\n  async function dispatchHandler(currentIndex: number): Promise<void> {\n    if (currentIndex <= middlewaresIndex) {\n      throw new Error(\"next() called multiple times\");\n    }\n    middlewaresIndex = currentIndex;\n    let handlerFn: MiddlewareFn<any>;\n    if (currentIndex === middlewares.length) {\n      handlerFn = resolverHandlerFunction;\n    } else {\n      const currentMiddleware = middlewares[currentIndex];\n      // Arrow function or class\n      if (currentMiddleware.prototype !== undefined) {\n        const middlewareClassInstance = await container.getInstance(\n          currentMiddleware as MiddlewareClass<any>,\n          resolverData,\n        );\n        handlerFn = middlewareClassInstance.use.bind(middlewareClassInstance);\n      } else {\n        handlerFn = currentMiddleware as MiddlewareFn<any>;\n      }\n    }\n    let nextResult: any;\n    const result = await handlerFn(resolverData, async () => {\n      nextResult = await dispatchHandler(currentIndex + 1);\n      return nextResult;\n    });\n    return result !== undefined ? result : nextResult;\n  }\n\n  return dispatchHandler(0);\n}\n"
  },
  {
    "path": "src/resolvers/validate-arg.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore 'class-validator' might not be installed by user\nimport { type ValidationError, type ValidatorOptions } from \"class-validator\";\nimport { type TypeValue } from \"@/decorators/types\";\nimport { ArgumentValidationError } from \"@/errors\";\nimport { type ValidateSettings } from \"@/schema/build-context\";\nimport { type ResolverData, type ValidatorFn } from \"@/typings\";\n\nconst shouldArgBeValidated = (argValue: unknown): boolean =>\n  argValue !== null && typeof argValue === \"object\";\n\nexport async function validateArg(\n  argValue: any | undefined,\n  argType: TypeValue,\n  resolverData: ResolverData,\n  globalValidateSettings: ValidateSettings,\n  argValidateSettings: ValidateSettings | undefined,\n  globalValidateFn: ValidatorFn | undefined,\n  argValidateFn: ValidatorFn | undefined,\n): Promise<any | undefined> {\n  const validateFn = argValidateFn ?? globalValidateFn;\n  if (typeof validateFn === \"function\") {\n    await validateFn(argValue, argType, resolverData);\n    return argValue;\n  }\n\n  const validate = argValidateSettings !== undefined ? argValidateSettings : globalValidateSettings;\n  if (validate === false || !shouldArgBeValidated(argValue)) {\n    return argValue;\n  }\n\n  const validatorOptions: ValidatorOptions = {\n    ...(typeof globalValidateSettings === \"object\" ? globalValidateSettings : {}),\n    ...(typeof argValidateSettings === \"object\" ? argValidateSettings : {}),\n  };\n  if (validatorOptions.skipMissingProperties !== false) {\n    validatorOptions.skipMissingProperties = true;\n  }\n  if (validatorOptions.forbidUnknownValues !== true) {\n    validatorOptions.forbidUnknownValues = false;\n  }\n\n  // Dynamic import to avoid making 'class-validator' a peer dependency when `validate: true` is not set\n  const { validateOrReject } = await import(\"class-validator\");\n  try {\n    if (Array.isArray(argValue)) {\n      await Promise.all(\n        argValue\n          .filter(shouldArgBeValidated)\n          .map(argItem => validateOrReject(argItem, validatorOptions)),\n      );\n    } else {\n      await validateOrReject(argValue, validatorOptions);\n    }\n    return argValue;\n  } catch (err) {\n    throw new ArgumentValidationError(err as ValidationError[]);\n  }\n}\n"
  },
  {
    "path": "src/scalars/aliases.ts",
    "content": "import { GraphQLFloat, GraphQLID, GraphQLInt } from \"graphql\";\n\nexport const Int = GraphQLInt;\nexport const Float = GraphQLFloat;\nexport const ID = GraphQLID;\n"
  },
  {
    "path": "src/scalars/index.ts",
    "content": "export * from \"./aliases\";\nexport { GraphQLTimestamp, GraphQLDateTimeISO as GraphQLISODateTime } from \"graphql-scalars\";\n"
  },
  {
    "path": "src/schema/build-context.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore 'class-validator' might not be installed by user\nimport { type ValidatorOptions } from \"class-validator\";\nimport { type GraphQLScalarType } from \"graphql\";\nimport { type AuthChecker, type AuthMode } from \"@/typings\";\nimport { type Middleware } from \"@/typings/middleware\";\nimport { type PubSub } from \"@/typings/subscriptions\";\nimport { type ValidatorFn } from \"@/typings/ValidatorFn\";\nimport { type ContainerGetter, type ContainerType, IOCContainer } from \"@/utils/container\";\n\nexport interface ScalarsTypeMap {\n  type: Function;\n  scalar: GraphQLScalarType;\n}\n\nexport type ValidateSettings = boolean | ValidatorOptions;\n\nexport interface BuildContextOptions {\n  scalarsMap?: ScalarsTypeMap[];\n  /**\n   * Indicates if class-validator should be used to auto validate objects injected into params.\n   * You can directly pass validator options to enable validator with a given options.\n   */\n  validate?: ValidateSettings;\n  /**\n   * Own validation function to check the args and inputs.\n   */\n  validateFn?: ValidatorFn;\n  authChecker?: AuthChecker<any, any>;\n  authMode?: AuthMode;\n  pubSub?: PubSub;\n  globalMiddlewares?: Array<Middleware<any>>;\n  container?: ContainerType | ContainerGetter<any>;\n  /**\n   * Default value for type decorators, like `@Field({ nullable: true })`\n   */\n  nullableByDefault?: boolean;\n  /**\n   * Disable inferring default values from property initializers, like `created = new Date();`\n   */\n  disableInferringDefaultValues?: boolean;\n}\n\nexport abstract class BuildContext {\n  static scalarsMaps: ScalarsTypeMap[];\n\n  static validate: ValidateSettings;\n\n  static validateFn?: ValidatorFn;\n\n  static authChecker?: AuthChecker<any, any>;\n\n  static authMode: AuthMode;\n\n  static pubSub?: PubSub;\n\n  static globalMiddlewares: Array<Middleware<any>>;\n\n  static container: IOCContainer;\n\n  static nullableByDefault: boolean;\n\n  static disableInferringDefaultValues: boolean;\n\n  /**\n   * Set static fields with current building context data\n   */\n  static create(options: BuildContextOptions) {\n    if (options.scalarsMap !== undefined) {\n      this.scalarsMaps = options.scalarsMap;\n    }\n\n    if (options.validate !== undefined) {\n      this.validate = options.validate;\n    }\n\n    if (options.validateFn !== undefined) {\n      this.validateFn = options.validateFn;\n    }\n\n    if (options.authChecker !== undefined) {\n      this.authChecker = options.authChecker;\n    }\n\n    if (options.authMode !== undefined) {\n      this.authMode = options.authMode;\n    }\n\n    if (options.pubSub !== undefined) {\n      this.pubSub = options.pubSub;\n    }\n\n    if (options.globalMiddlewares) {\n      this.globalMiddlewares = options.globalMiddlewares;\n    }\n\n    if (options.nullableByDefault !== undefined) {\n      this.nullableByDefault = options.nullableByDefault;\n    }\n\n    if (options.disableInferringDefaultValues !== undefined) {\n      this.disableInferringDefaultValues = options.disableInferringDefaultValues;\n    }\n\n    this.container = new IOCContainer(options.container);\n  }\n\n  /**\n   * Restore default settings\n   */\n  static reset() {\n    this.scalarsMaps = [];\n    this.validate = false;\n    this.validateFn = undefined;\n    this.authChecker = undefined;\n    this.authMode = \"error\";\n    this.pubSub = undefined;\n    this.globalMiddlewares = [];\n    this.container = new IOCContainer();\n    this.nullableByDefault = false;\n    this.disableInferringDefaultValues = false;\n  }\n}\n\n// Initialize fields\nBuildContext.reset();\n"
  },
  {
    "path": "src/schema/definition-node.ts",
    "content": "import {\n  type ConstArgumentNode,\n  type ConstDirectiveNode,\n  type DocumentNode,\n  type FieldDefinitionNode,\n  type GraphQLInputType,\n  type GraphQLOutputType,\n  type InputObjectTypeDefinitionNode,\n  type InputValueDefinitionNode,\n  type InterfaceTypeDefinitionNode,\n  Kind,\n  type ObjectTypeDefinitionNode,\n  parse,\n  parseConstValue,\n} from \"graphql\";\nimport { InvalidDirectiveError } from \"@/errors\";\nimport { type DirectiveMetadata } from \"@/metadata/definitions\";\nimport { type SetRequired } from \"@/typings\";\n\nexport function getDirectiveNode(directive: DirectiveMetadata): ConstDirectiveNode {\n  // Inline and trim start\n  const nameOrDefinition = directive.nameOrDefinition.replaceAll(\"\\n\", \" \").trimStart();\n  const { args } = directive;\n\n  if (nameOrDefinition === \"\") {\n    throw new InvalidDirectiveError(\n      \"Please pass at-least one directive name or definition to the @Directive decorator\",\n    );\n  }\n\n  if (!nameOrDefinition.startsWith(\"@\")) {\n    return {\n      kind: Kind.DIRECTIVE,\n      name: {\n        kind: Kind.NAME,\n        value: nameOrDefinition,\n      },\n      arguments: Object.keys(args).map<ConstArgumentNode>(argKey => ({\n        kind: Kind.ARGUMENT,\n        name: {\n          kind: Kind.NAME,\n          value: argKey,\n        },\n        value: parseConstValue(args[argKey]),\n      })),\n    };\n  }\n\n  let parsed: DocumentNode;\n  try {\n    parsed = parse(`type String ${nameOrDefinition}`);\n  } catch (err) {\n    throw new InvalidDirectiveError(\n      `Error parsing directive definition \"${directive.nameOrDefinition}\"`,\n    );\n  }\n\n  const definitions = parsed.definitions as ObjectTypeDefinitionNode[];\n  const directives = definitions\n    .filter(\n      (it): it is SetRequired<ObjectTypeDefinitionNode, \"directives\"> =>\n        !!it.directives && it.directives.length > 0,\n    )\n    .map(it => it.directives)\n    .flat();\n\n  if (directives.length !== 1) {\n    throw new InvalidDirectiveError(\n      `Please pass only one directive name or definition at a time to the @Directive decorator \"${directive.nameOrDefinition}\"`,\n    );\n  }\n\n  return directives[0];\n}\n\nexport function getObjectTypeDefinitionNode(\n  name: string,\n  directiveMetadata?: DirectiveMetadata[],\n): ObjectTypeDefinitionNode | undefined {\n  if (!directiveMetadata || !directiveMetadata.length) {\n    return undefined;\n  }\n\n  return {\n    kind: Kind.OBJECT_TYPE_DEFINITION,\n    name: {\n      kind: Kind.NAME,\n      // FIXME: use proper AST representation\n      value: name,\n    },\n    directives: directiveMetadata.map(getDirectiveNode),\n  };\n}\n\nexport function getInputObjectTypeDefinitionNode(\n  name: string,\n  directiveMetadata?: DirectiveMetadata[],\n): InputObjectTypeDefinitionNode | undefined {\n  if (!directiveMetadata || !directiveMetadata.length) {\n    return undefined;\n  }\n\n  return {\n    kind: Kind.INPUT_OBJECT_TYPE_DEFINITION,\n    name: {\n      kind: Kind.NAME,\n      // FIXME: use proper AST representation\n      value: name,\n    },\n    directives: directiveMetadata.map(getDirectiveNode),\n  };\n}\n\nexport function getFieldDefinitionNode(\n  name: string,\n  type: GraphQLOutputType,\n  directiveMetadata?: DirectiveMetadata[],\n): FieldDefinitionNode | undefined {\n  if (!directiveMetadata || !directiveMetadata.length) {\n    return undefined;\n  }\n\n  return {\n    kind: Kind.FIELD_DEFINITION,\n    type: {\n      kind: Kind.NAMED_TYPE,\n      name: {\n        kind: Kind.NAME,\n        value: type.toString(),\n      },\n    },\n    name: {\n      kind: Kind.NAME,\n      value: name,\n    },\n    directives: directiveMetadata.map(getDirectiveNode),\n  };\n}\n\nexport function getInputValueDefinitionNode(\n  name: string,\n  type: GraphQLInputType,\n  directiveMetadata?: DirectiveMetadata[],\n): InputValueDefinitionNode | undefined {\n  if (!directiveMetadata || !directiveMetadata.length) {\n    return undefined;\n  }\n\n  return {\n    kind: Kind.INPUT_VALUE_DEFINITION,\n    type: {\n      kind: Kind.NAMED_TYPE,\n      name: {\n        kind: Kind.NAME,\n        value: type.toString(),\n      },\n    },\n    name: {\n      kind: Kind.NAME,\n      value: name,\n    },\n    directives: directiveMetadata.map(getDirectiveNode),\n  };\n}\n\nexport function getInterfaceTypeDefinitionNode(\n  name: string,\n  directiveMetadata?: DirectiveMetadata[],\n): InterfaceTypeDefinitionNode | undefined {\n  if (!directiveMetadata || !directiveMetadata.length) {\n    return undefined;\n  }\n\n  return {\n    kind: Kind.INTERFACE_TYPE_DEFINITION,\n    name: {\n      kind: Kind.NAME,\n      // FIXME: use proper AST representation\n      value: name,\n    },\n    directives: directiveMetadata.map(getDirectiveNode),\n  };\n}\n"
  },
  {
    "path": "src/schema/schema-generator.ts",
    "content": "import { Repeater, filter, pipe } from \"@graphql-yoga/subscription\";\nimport {\n  type GraphQLDirective,\n  GraphQLEnumType,\n  type GraphQLEnumValueConfigMap,\n  type GraphQLFieldConfigArgumentMap,\n  type GraphQLFieldConfigMap,\n  type GraphQLFieldResolver,\n  type GraphQLInputFieldConfigMap,\n  GraphQLInputObjectType,\n  type GraphQLInputType,\n  GraphQLInterfaceType,\n  type GraphQLNamedType,\n  GraphQLObjectType,\n  type GraphQLOutputType,\n  GraphQLSchema,\n  type GraphQLTypeResolver,\n  GraphQLUnionType,\n  getIntrospectionQuery,\n  graphqlSync,\n} from \"graphql\";\nimport { type TypeOptions, type TypeValue } from \"@/decorators/types\";\nimport {\n  CannotDetermineGraphQLTypeError,\n  ConflictingDefaultValuesError,\n  GeneratingSchemaError,\n  InterfaceResolveTypeError,\n  MissingPubSubError,\n  MissingSubscriptionTopicsError,\n  UnionResolveTypeError,\n} from \"@/errors\";\nimport { convertTypeIfScalar, getEnumValuesMap, wrapWithTypeOptions } from \"@/helpers/types\";\nimport {\n  type ClassMetadata,\n  type FieldMetadata,\n  type ParamMetadata,\n  type ResolverMetadata,\n  type SubscriptionResolverMetadata,\n} from \"@/metadata/definitions\";\nimport { type InterfaceClassMetadata } from \"@/metadata/definitions/interface-class-metadata\";\nimport { type ObjectClassMetadata } from \"@/metadata/definitions/object-class-metadata\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type MetadataStorage } from \"@/metadata/metadata-storage\";\nimport {\n  createAdvancedFieldResolver,\n  createBasicFieldResolver,\n  createHandlerResolver,\n  wrapResolverWithAuthChecker,\n} from \"@/resolvers/create\";\nimport {\n  type MaybePromise,\n  type SubscribeResolverData,\n  type SubscriptionHandlerData,\n  type TypeResolver,\n} from \"@/typings\";\nimport { ensureInstalledCorrectGraphQLPackage } from \"@/utils/graphql-version\";\nimport { BuildContext, type BuildContextOptions } from \"./build-context\";\nimport {\n  getFieldDefinitionNode,\n  getInputObjectTypeDefinitionNode,\n  getInputValueDefinitionNode,\n  getInterfaceTypeDefinitionNode,\n  getObjectTypeDefinitionNode,\n} from \"./definition-node\";\nimport { getFieldMetadataFromInputType, getFieldMetadataFromObjectType } from \"./utils\";\n\ninterface ObjectTypeInfo {\n  target: Function;\n  type: GraphQLObjectType;\n  metadata: ObjectClassMetadata;\n}\ninterface InterfaceTypeInfo {\n  target: Function;\n  type: GraphQLInterfaceType;\n  metadata: InterfaceClassMetadata;\n}\ninterface InputObjectTypeInfo {\n  target: Function;\n  type: GraphQLInputObjectType;\n}\ninterface EnumTypeInfo {\n  enumObj: object;\n  type: GraphQLEnumType;\n}\ninterface UnionTypeInfo {\n  unionSymbol: symbol;\n  type: GraphQLUnionType;\n}\n\nexport type SchemaGeneratorOptions = {\n  /**\n   * Array of resolvers classes\n   */\n  resolvers: Function[];\n  /**\n   * Array of orphaned type classes that are not used explicitly in GraphQL types definitions\n   */\n  orphanedTypes?: Function[];\n  /**\n   * Disable checking on build the correctness of a schema\n   */\n  skipCheck?: boolean;\n  /**\n   * Array of graphql directives\n   */\n  directives?: GraphQLDirective[];\n} & BuildContextOptions;\n\nexport abstract class SchemaGenerator {\n  private static objectTypesInfoMap = new Map<Function, ObjectTypeInfo>();\n\n  private static inputTypesInfoMap = new Map<Function, InputObjectTypeInfo>();\n\n  private static interfaceTypesInfoMap = new Map<Function, InterfaceTypeInfo>();\n\n  private static enumTypesInfoMap = new Map<object, EnumTypeInfo>();\n\n  private static unionTypesInfoMap = new Map<symbol, UnionTypeInfo>();\n\n  private static usedInterfaceTypes = new Set<Function>();\n\n  private static metadataStorage: MetadataStorage;\n\n  static generateFromMetadata(options: SchemaGeneratorOptions): GraphQLSchema {\n    this.metadataStorage = getMetadataStorage().clone();\n    this.metadataStorage.build(options);\n\n    this.checkForErrors(options);\n    BuildContext.create(options);\n\n    this.buildTypesInfo(options.resolvers);\n\n    const orphanedTypes = options.orphanedTypes ?? [];\n    const prebuiltSchema = new GraphQLSchema({\n      query: this.buildRootQueryType(options.resolvers),\n      mutation: this.buildRootMutationType(options.resolvers),\n      subscription: this.buildRootSubscriptionType(options.resolvers),\n      directives: options.directives,\n    });\n    const finalSchema = new GraphQLSchema({\n      ...prebuiltSchema.toConfig(),\n      // run after first build to make `usedInterfaceTypes` working\n      types: this.buildOtherTypes(orphanedTypes),\n    });\n\n    // cleanup after build to prevent memory leaks\n    // and to reset state for next possible builds\n    BuildContext.reset();\n    this.usedInterfaceTypes = new Set<Function>();\n    this.objectTypesInfoMap = new Map<Function, ObjectTypeInfo>();\n    this.inputTypesInfoMap = new Map<Function, InputObjectTypeInfo>();\n    this.interfaceTypesInfoMap = new Map<Function, InterfaceTypeInfo>();\n    this.enumTypesInfoMap = new Map<object, EnumTypeInfo>();\n    this.unionTypesInfoMap = new Map<symbol, UnionTypeInfo>();\n\n    if (!options.skipCheck) {\n      const { errors } = graphqlSync({ schema: finalSchema, source: getIntrospectionQuery() });\n      if (errors) {\n        throw new GeneratingSchemaError(errors);\n      }\n    }\n\n    return finalSchema;\n  }\n\n  private static checkForErrors(options: SchemaGeneratorOptions) {\n    ensureInstalledCorrectGraphQLPackage();\n    if (this.metadataStorage.authorizedFields.length !== 0 && options.authChecker === undefined) {\n      throw new Error(\n        \"You need to provide `authChecker` function for `@Authorized` decorator usage!\",\n      );\n    }\n  }\n\n  private static getDefaultValue(\n    typeInstance: Record<string, unknown>,\n    typeOptions: TypeOptions,\n    fieldName: string,\n    typeName: string,\n  ): unknown | undefined {\n    const { disableInferringDefaultValues } = BuildContext;\n    if (disableInferringDefaultValues) {\n      return typeOptions.defaultValue;\n    }\n\n    const defaultValueFromInitializer = typeInstance[fieldName];\n    if (\n      typeOptions.defaultValue !== undefined &&\n      defaultValueFromInitializer !== undefined &&\n      typeOptions.defaultValue !== defaultValueFromInitializer\n    ) {\n      throw new ConflictingDefaultValuesError(\n        typeName,\n        fieldName,\n        typeOptions.defaultValue,\n        defaultValueFromInitializer,\n      );\n    }\n    return typeOptions.defaultValue !== undefined\n      ? typeOptions.defaultValue\n      : defaultValueFromInitializer;\n  }\n\n  private static buildTypesInfo(resolvers: Function[]) {\n    this.unionTypesInfoMap = new Map<symbol, UnionTypeInfo>(\n      this.metadataStorage.unions.map(unionMetadata => {\n        // use closure to capture values from this selected schema build\n        const unionObjectTypesInfo: ObjectTypeInfo[] = [];\n        // called once after building all `objectTypesInfo`\n        const typesThunk = () => {\n          unionObjectTypesInfo.push(\n            ...unionMetadata\n              .getClassTypes()\n              .map(objectTypeCls => this.objectTypesInfoMap.get(objectTypeCls)!),\n          );\n          return unionObjectTypesInfo.map(it => it.type);\n        };\n        const unionTypeInfo: UnionTypeInfo = {\n          unionSymbol: unionMetadata.symbol,\n          type: new GraphQLUnionType({\n            name: unionMetadata.name,\n            description: unionMetadata.description,\n            types: typesThunk,\n            resolveType: unionMetadata.resolveType\n              ? this.getResolveTypeFunction(\n                  unionMetadata.resolveType,\n                  // use closure captured `unionObjectTypesInfo`\n                  unionObjectTypesInfo,\n                )\n              : instance => {\n                  const instanceTarget = unionMetadata\n                    .getClassTypes()\n                    .find(ObjectClassType => instance instanceof ObjectClassType);\n                  if (!instanceTarget) {\n                    throw new UnionResolveTypeError(unionMetadata);\n                  }\n                  // use closure captured `unionObjectTypesInfo`\n                  const objectTypeInfo = unionObjectTypesInfo.find(\n                    type => type.target === instanceTarget,\n                  );\n                  return objectTypeInfo?.type.name;\n                },\n          }),\n        };\n\n        return [unionMetadata.symbol, unionTypeInfo];\n      }),\n    );\n\n    this.enumTypesInfoMap = new Map<object, EnumTypeInfo>(\n      this.metadataStorage.enums.map(enumMetadata => {\n        const enumMap = getEnumValuesMap(enumMetadata.enumObj);\n        const enumTypeInfo: EnumTypeInfo = {\n          enumObj: enumMetadata.enumObj,\n          type: new GraphQLEnumType({\n            name: enumMetadata.name,\n            description: enumMetadata.description,\n            values: Object.keys(enumMap).reduce<GraphQLEnumValueConfigMap>(\n              (enumConfig, enumKey) => {\n                const valueConfig = enumMetadata.valuesConfig[enumKey] || {};\n                // eslint-disable-next-line no-param-reassign\n                enumConfig[enumKey] = {\n                  value: enumMap[enumKey],\n                  description: valueConfig.description,\n                  deprecationReason: valueConfig.deprecationReason,\n                };\n                return enumConfig;\n              },\n              {},\n            ),\n          }),\n        };\n\n        return [enumMetadata.enumObj, enumTypeInfo];\n      }),\n    );\n\n    this.objectTypesInfoMap = new Map<Function, ObjectTypeInfo>(\n      this.metadataStorage.objectTypes.map(objectType => {\n        const objectSuperClass = Object.getPrototypeOf(objectType.target);\n        const hasExtended = objectSuperClass.prototype !== undefined;\n        const getSuperClassType = () => {\n          const superClassTypeInfo =\n            this.objectTypesInfoMap.get(objectSuperClass) ??\n            this.interfaceTypesInfoMap.get(objectSuperClass);\n          return superClassTypeInfo ? superClassTypeInfo.type : undefined;\n        };\n        const interfaceClasses = objectType.interfaceClasses || [];\n        const objectTypeInfo: ObjectTypeInfo = {\n          metadata: objectType,\n          target: objectType.target,\n          type: new GraphQLObjectType({\n            name: objectType.name,\n            description: objectType.description,\n            astNode: getObjectTypeDefinitionNode(objectType.name, objectType.directives),\n            extensions: objectType.extensions,\n            interfaces: () => {\n              let interfaces = interfaceClasses.map<GraphQLInterfaceType>(interfaceClass => {\n                const interfaceTypeInfo = this.interfaceTypesInfoMap.get(interfaceClass);\n                if (!interfaceTypeInfo) {\n                  throw new Error(\n                    `Cannot find interface type metadata for class '${interfaceClass.name}' ` +\n                      `provided in 'implements' option for '${objectType.target.name}' object type class. ` +\n                      `Please make sure that class is annotated with an '@InterfaceType()' decorator.`,\n                  );\n                }\n                return interfaceTypeInfo.type;\n              });\n              // copy interfaces from super class\n              if (hasExtended) {\n                const superClass = getSuperClassType();\n                if (superClass) {\n                  const superInterfaces = superClass.getInterfaces();\n                  interfaces = Array.from(new Set(interfaces.concat(superInterfaces)));\n                }\n              }\n              return interfaces;\n            },\n            fields: () => {\n              const fieldsMetadata: FieldMetadata[] = [];\n              // support for implicitly implementing interfaces\n              // get fields from interfaces definitions\n              if (objectType.interfaceClasses) {\n                const implementedInterfaces = this.metadataStorage.interfaceTypes.filter(it =>\n                  objectType.interfaceClasses!.includes(it.target),\n                );\n                implementedInterfaces.forEach(it => {\n                  fieldsMetadata.push(...(it.fields || []));\n                });\n              }\n              // push own fields at the end to overwrite the one inherited from interface\n              fieldsMetadata.push(...objectType.fields!);\n\n              let fields = fieldsMetadata.reduce<GraphQLFieldConfigMap<any, any>>(\n                (fieldsMap, field) => {\n                  const { fieldResolvers } = this.metadataStorage;\n                  const filteredFieldResolversMetadata = fieldResolvers.filter(\n                    it => it.kind === \"internal\" || resolvers.includes(it.target),\n                  );\n                  const fieldResolverMetadata = filteredFieldResolversMetadata.find(\n                    it =>\n                      it.getObjectType!() === field.target && it.schemaName === field.schemaName,\n                  );\n                  const type = this.getGraphQLOutputType(\n                    field.target,\n                    field.name,\n                    field.getType(),\n                    field.typeOptions,\n                  );\n                  const isSimpleResolver =\n                    // eslint-disable-next-line no-nested-ternary\n                    field.simple !== undefined\n                      ? field.simple === true\n                      : objectType.simpleResolvers !== undefined\n                        ? objectType.simpleResolvers === true\n                        : false;\n                  // eslint-disable-next-line no-param-reassign\n                  fieldsMap[field.schemaName] = {\n                    type,\n                    args: this.generateHandlerArgs(field.target, field.name, field.params!),\n                    // eslint-disable-next-line no-nested-ternary\n                    resolve: fieldResolverMetadata\n                      ? createAdvancedFieldResolver(fieldResolverMetadata)\n                      : isSimpleResolver\n                        ? undefined\n                        : createBasicFieldResolver(field),\n                    description: field.description,\n                    deprecationReason: field.deprecationReason,\n                    astNode: getFieldDefinitionNode(field.name, type, field.directives),\n                    extensions: {\n                      complexity: field.complexity,\n                      ...field.extensions,\n                      ...fieldResolverMetadata?.extensions,\n                    },\n                  };\n                  return fieldsMap;\n                },\n                {},\n              );\n              // support for extending classes - get field info from prototype\n              if (hasExtended) {\n                const superClass = getSuperClassType();\n                if (superClass) {\n                  const superClassFields = getFieldMetadataFromObjectType(superClass);\n                  fields = { ...superClassFields, ...fields };\n                }\n              }\n              return fields;\n            },\n          }),\n        };\n\n        return [objectType.target, objectTypeInfo];\n      }),\n    );\n\n    this.interfaceTypesInfoMap = new Map<Function, InterfaceTypeInfo>(\n      this.metadataStorage.interfaceTypes.map(interfaceType => {\n        const interfaceSuperClass = Object.getPrototypeOf(interfaceType.target);\n        const hasExtended = interfaceSuperClass.prototype !== undefined;\n        const getSuperClassType = () => {\n          const superClassTypeInfo = this.interfaceTypesInfoMap.get(interfaceSuperClass);\n          return superClassTypeInfo ? superClassTypeInfo.type : undefined;\n        };\n\n        // fetch ahead the subset of object types that implements this interface\n        const implementingObjectTypesTargets = this.metadataStorage.objectTypes\n          .filter(\n            objectType =>\n              objectType.interfaceClasses &&\n              objectType.interfaceClasses.includes(interfaceType.target),\n          )\n          .map(objectType => objectType.target);\n        const implementingObjectTypesInfo = [...this.objectTypesInfoMap.values()].filter(\n          objectTypesInfo => implementingObjectTypesTargets.includes(objectTypesInfo.target),\n        );\n\n        const interfaceTypeInfo: InterfaceTypeInfo = {\n          metadata: interfaceType,\n          target: interfaceType.target,\n          type: new GraphQLInterfaceType({\n            name: interfaceType.name,\n            description: interfaceType.description,\n            astNode: getInterfaceTypeDefinitionNode(interfaceType.name, interfaceType.directives),\n            extensions: interfaceType.extensions,\n            interfaces: () => {\n              let interfaces = (interfaceType.interfaceClasses || []).map<GraphQLInterfaceType>(\n                interfaceClass => this.interfaceTypesInfoMap.get(interfaceClass)!.type,\n              );\n              // copy interfaces from super class\n              if (hasExtended) {\n                const superClass = getSuperClassType();\n                if (superClass) {\n                  const superInterfaces = superClass.getInterfaces();\n                  interfaces = Array.from(new Set(interfaces.concat(superInterfaces)));\n                }\n              }\n              return interfaces;\n            },\n            fields: () => {\n              const fieldsMetadata: FieldMetadata[] = [];\n              // support for implicitly implementing interfaces\n              // get fields from interfaces definitions\n              if (interfaceType.interfaceClasses) {\n                const implementedInterfacesMetadata = this.metadataStorage.interfaceTypes.filter(\n                  it => interfaceType.interfaceClasses!.includes(it.target),\n                );\n                implementedInterfacesMetadata.forEach(it => {\n                  fieldsMetadata.push(...(it.fields || []));\n                });\n              }\n              // push own fields at the end to overwrite the one inherited from interface\n              fieldsMetadata.push(...interfaceType.fields!);\n\n              let fields = fieldsMetadata!.reduce<GraphQLFieldConfigMap<any, any>>(\n                (fieldsMap, field) => {\n                  const fieldResolverMetadata = this.metadataStorage.fieldResolvers.find(\n                    resolver =>\n                      resolver.getObjectType!() === field.target &&\n                      resolver.schemaName === field.schemaName,\n                  );\n                  const type = this.getGraphQLOutputType(\n                    field.target,\n                    field.name,\n                    field.getType(),\n                    field.typeOptions,\n                  );\n                  // eslint-disable-next-line no-param-reassign\n                  fieldsMap[field.schemaName] = {\n                    type,\n                    args: this.generateHandlerArgs(field.target, field.name, field.params!),\n                    resolve: fieldResolverMetadata\n                      ? createAdvancedFieldResolver(fieldResolverMetadata)\n                      : createBasicFieldResolver(field),\n                    description: field.description,\n                    deprecationReason: field.deprecationReason,\n                    astNode: getFieldDefinitionNode(field.name, type, field.directives),\n                    extensions: {\n                      complexity: field.complexity,\n                      ...field.extensions,\n                    },\n                  };\n                  return fieldsMap;\n                },\n                {},\n              );\n              // support for extending interface classes - get field info from prototype\n              if (hasExtended) {\n                const superClass = getSuperClassType();\n                if (superClass) {\n                  const superClassFields = getFieldMetadataFromObjectType(superClass);\n                  fields = { ...superClassFields, ...fields };\n                }\n              }\n              return fields;\n            },\n            resolveType: interfaceType.resolveType\n              ? this.getResolveTypeFunction(interfaceType.resolveType, implementingObjectTypesInfo)\n              : instance => {\n                  const typeTarget = implementingObjectTypesTargets.find(\n                    typeCls => instance instanceof typeCls,\n                  );\n                  if (!typeTarget) {\n                    throw new InterfaceResolveTypeError(interfaceType);\n                  }\n                  const objectTypeInfo = implementingObjectTypesInfo.find(\n                    type => type.target === typeTarget,\n                  );\n                  return objectTypeInfo?.type.name;\n                },\n          }),\n        };\n\n        return [interfaceType.target, interfaceTypeInfo];\n      }),\n    );\n\n    this.inputTypesInfoMap = new Map<Function, InputObjectTypeInfo>(\n      this.metadataStorage.inputTypes.map(inputType => {\n        const objectSuperClass = Object.getPrototypeOf(inputType.target);\n        const getSuperClassType = () => {\n          const superClassTypeInfo = this.inputTypesInfoMap.get(objectSuperClass);\n          return superClassTypeInfo ? superClassTypeInfo.type : undefined;\n        };\n        const inputInstance = new (inputType.target as any)();\n        const inputTypeInfo: InputObjectTypeInfo = {\n          target: inputType.target,\n          type: new GraphQLInputObjectType({\n            name: inputType.name,\n            description: inputType.description,\n            extensions: inputType.extensions,\n            fields: () => {\n              let fields = inputType.fields!.reduce<GraphQLInputFieldConfigMap>(\n                (fieldsMap, field) => {\n                  const defaultValue = this.getDefaultValue(\n                    inputInstance,\n                    field.typeOptions,\n                    field.name,\n                    inputType.name,\n                  );\n\n                  const type = this.getGraphQLInputType(field.target, field.name, field.getType(), {\n                    ...field.typeOptions,\n                    defaultValue,\n                  });\n                  // eslint-disable-next-line no-param-reassign\n                  fieldsMap[field.name] = {\n                    description: field.description,\n                    type,\n                    defaultValue,\n                    astNode: getInputValueDefinitionNode(field.name, type, field.directives),\n                    extensions: field.extensions,\n                    deprecationReason: field.deprecationReason,\n                  };\n                  return fieldsMap;\n                },\n                {},\n              );\n              // support for extending classes - get field info from prototype\n              if (objectSuperClass.prototype !== undefined) {\n                const superClass = getSuperClassType();\n                if (superClass) {\n                  const superClassFields = getFieldMetadataFromInputType(superClass);\n                  fields = { ...superClassFields, ...fields };\n                }\n              }\n              return fields;\n            },\n            astNode: getInputObjectTypeDefinitionNode(inputType.name, inputType.directives),\n          }),\n        };\n\n        return [inputType.target, inputTypeInfo];\n      }),\n    );\n  }\n\n  private static buildRootQueryType(resolvers: Function[]): GraphQLObjectType {\n    const queriesHandlers = this.filterHandlersByResolvers(this.metadataStorage.queries, resolvers);\n\n    return new GraphQLObjectType({\n      name: \"Query\",\n      fields: this.generateHandlerFields(queriesHandlers),\n    });\n  }\n\n  private static buildRootMutationType(resolvers: Function[]): GraphQLObjectType | undefined {\n    const mutationsHandlers = this.filterHandlersByResolvers(\n      this.metadataStorage.mutations,\n      resolvers,\n    );\n    if (mutationsHandlers.length === 0) {\n      return undefined;\n    }\n\n    return new GraphQLObjectType({\n      name: \"Mutation\",\n      fields: this.generateHandlerFields(mutationsHandlers),\n    });\n  }\n\n  private static buildRootSubscriptionType(resolvers: Function[]): GraphQLObjectType | undefined {\n    const subscriptionsHandlers = this.filterHandlersByResolvers(\n      this.metadataStorage.subscriptions,\n      resolvers,\n    );\n    if (subscriptionsHandlers.length === 0) {\n      return undefined;\n    }\n\n    return new GraphQLObjectType({\n      name: \"Subscription\",\n      fields: this.generateSubscriptionsFields(subscriptionsHandlers),\n    });\n  }\n\n  private static buildOtherTypes(orphanedTypes: Function[]): GraphQLNamedType[] {\n    const autoRegisteredObjectTypesInfo = [...this.objectTypesInfoMap.values()].filter(typeInfo =>\n      typeInfo.metadata.interfaceClasses?.some(interfaceClass => {\n        const implementedInterfaceInfo = this.interfaceTypesInfoMap.get(interfaceClass);\n        if (!implementedInterfaceInfo) {\n          return false;\n        }\n        if (implementedInterfaceInfo.metadata.autoRegisteringDisabled) {\n          return false;\n        }\n        if (!this.usedInterfaceTypes.has(interfaceClass)) {\n          return false;\n        }\n        return true;\n      }),\n    );\n    return [\n      ...this.filterTypesInfoByOrphanedTypesAndExtractType(\n        [...this.objectTypesInfoMap.values()],\n        orphanedTypes,\n      ),\n      ...this.filterTypesInfoByOrphanedTypesAndExtractType(\n        [...this.interfaceTypesInfoMap.values()],\n        orphanedTypes,\n      ),\n      ...this.filterTypesInfoByOrphanedTypesAndExtractType(\n        [...this.inputTypesInfoMap.values()],\n        orphanedTypes,\n      ),\n      ...autoRegisteredObjectTypesInfo.map(typeInfo => typeInfo.type),\n    ];\n  }\n\n  private static generateHandlerFields<T = any, U = any>(\n    handlers: ResolverMetadata[],\n  ): GraphQLFieldConfigMap<T, U> {\n    return handlers.reduce<GraphQLFieldConfigMap<T, U>>((fields, handler) => {\n      const type = this.getGraphQLOutputType(\n        handler.target,\n        handler.methodName,\n        handler.getReturnType(),\n        handler.returnTypeOptions,\n      );\n      // eslint-disable-next-line no-param-reassign\n      fields[handler.schemaName] = {\n        type,\n        args: this.generateHandlerArgs(handler.target, handler.methodName, handler.params!),\n        resolve: createHandlerResolver(handler),\n        description: handler.description,\n        deprecationReason: handler.deprecationReason,\n        astNode: getFieldDefinitionNode(handler.schemaName, type, handler.directives),\n        extensions: {\n          complexity: handler.complexity,\n          ...handler.extensions,\n        },\n      };\n      return fields;\n    }, {});\n  }\n\n  private static generateSubscriptionsFields<\n    TSource extends object = any,\n    TContext extends object = any,\n  >(\n    subscriptionsHandlers: SubscriptionResolverMetadata[],\n  ): GraphQLFieldConfigMap<TSource, TContext> {\n    if (!subscriptionsHandlers.length) {\n      return {};\n    }\n    const { pubSub, container } = BuildContext;\n    if (!pubSub) {\n      throw new MissingPubSubError();\n    }\n    const basicFields = this.generateHandlerFields(subscriptionsHandlers);\n    return subscriptionsHandlers.reduce<GraphQLFieldConfigMap<TSource, TContext>>(\n      (fields, handler) => {\n        let subscribeFn: GraphQLFieldResolver<\n          TSource,\n          TContext,\n          any,\n          MaybePromise<AsyncIterable<unknown>>\n        >;\n        if (handler.subscribe) {\n          subscribeFn = (source, args, context, info) => {\n            const subscribeResolverData: SubscribeResolverData = { source, args, context, info };\n            return handler.subscribe!(subscribeResolverData);\n          };\n        } else {\n          subscribeFn = (source, args, context, info) => {\n            const subscribeResolverData: SubscribeResolverData = { source, args, context, info };\n\n            let topics: string | string[];\n            if (typeof handler.topics === \"function\") {\n              const getTopics = handler.topics;\n              topics = getTopics(subscribeResolverData);\n            } else {\n              topics = handler.topics!;\n            }\n            const topicId = handler.topicId?.(subscribeResolverData);\n\n            let pubSubIterable: AsyncIterable<any>;\n            if (!Array.isArray(topics)) {\n              pubSubIterable = pubSub.subscribe(topics, topicId);\n            } else {\n              if (topics.length === 0) {\n                throw new MissingSubscriptionTopicsError(handler.target, handler.methodName);\n              }\n              pubSubIterable = Repeater.merge([\n                ...topics.map(topic => pubSub.subscribe(topic, topicId)),\n              ]);\n            }\n\n            if (!handler.filter) {\n              return pubSubIterable;\n            }\n\n            return pipe(\n              pubSubIterable,\n              filter(payload => {\n                const handlerData: SubscriptionHandlerData = { payload, args, context, info };\n                return handler.filter!(handlerData);\n              }),\n            );\n          };\n        }\n\n        // eslint-disable-next-line no-param-reassign\n        fields[handler.schemaName].subscribe = wrapResolverWithAuthChecker(\n          subscribeFn,\n          container,\n          handler.roles,\n        );\n        return fields;\n      },\n      basicFields,\n    );\n  }\n\n  private static generateHandlerArgs(\n    target: Function,\n    propertyName: string,\n    params: ParamMetadata[],\n  ): GraphQLFieldConfigArgumentMap {\n    return params!.reduce<GraphQLFieldConfigArgumentMap>((args, param) => {\n      if (param.kind === \"arg\" || (param.kind === \"custom\" && param.options?.arg)) {\n        const input = param.kind === \"arg\" ? param : param.options.arg!;\n\n        const type = this.getGraphQLInputType(\n          target,\n          propertyName,\n          input.getType(),\n          input.typeOptions,\n          input.index,\n          input.name,\n        );\n        const argDirectives = this.metadataStorage.argumentDirectives\n          .filter(\n            it =>\n              it.target === target &&\n              it.fieldName === propertyName &&\n              it.parameterIndex === param.index,\n          )\n          .map(it => it.directive);\n        // eslint-disable-next-line no-param-reassign\n        args[input.name] = {\n          description: input.description,\n          type,\n          defaultValue: input.typeOptions.defaultValue,\n          deprecationReason: input.deprecationReason,\n          astNode: getInputValueDefinitionNode(input.name, type, argDirectives),\n        };\n      } else if (param.kind === \"args\") {\n        const argumentType = this.metadataStorage.argumentTypes.find(\n          it => it.target === param.getType(),\n        );\n        if (!argumentType) {\n          throw new Error(\n            `The value used as a type of '@Args' for '${propertyName}' of '${target.name}' ` +\n              `is not a class decorated with '@ArgsType' decorator!`,\n          );\n        }\n\n        const inheritanceChainClasses: Function[] = [argumentType.target];\n        for (\n          let superClass = argumentType.target;\n          superClass.prototype !== undefined;\n          superClass = Object.getPrototypeOf(superClass)\n        ) {\n          inheritanceChainClasses.push(superClass);\n        }\n        for (const argsTypeClass of inheritanceChainClasses.reverse()) {\n          const inheritedArgumentType = this.metadataStorage.argumentTypes.find(\n            it => it.target === argsTypeClass,\n          );\n          if (inheritedArgumentType) {\n            this.mapArgFields(inheritedArgumentType, args);\n          }\n        }\n      }\n      return args;\n    }, {});\n  }\n\n  private static mapArgFields(\n    argumentType: ClassMetadata,\n    args: GraphQLFieldConfigArgumentMap = {},\n  ) {\n    const argumentInstance = new (argumentType.target as any)();\n    argumentType.fields!.forEach(field => {\n      const defaultValue = this.getDefaultValue(\n        argumentInstance,\n        field.typeOptions,\n        field.name,\n        argumentType.name,\n      );\n      const type = this.getGraphQLInputType(field.target, field.name, field.getType(), {\n        ...field.typeOptions,\n        defaultValue,\n      });\n      // eslint-disable-next-line no-param-reassign\n      args[field.schemaName] = {\n        description: field.description,\n        type,\n        defaultValue,\n        astNode: getInputValueDefinitionNode(field.name, type, field.directives),\n        extensions: field.extensions,\n        deprecationReason: field.deprecationReason,\n      };\n    });\n  }\n\n  private static getGraphQLOutputType(\n    target: Function,\n    propertyName: string,\n    type: TypeValue,\n    typeOptions: TypeOptions = {},\n  ): GraphQLOutputType {\n    let gqlType: GraphQLOutputType | undefined;\n    gqlType = convertTypeIfScalar(type);\n    if (!gqlType) {\n      const objectType = this.objectTypesInfoMap.get(type as Function);\n      if (objectType) {\n        gqlType = objectType.type;\n      }\n    }\n    if (!gqlType) {\n      const interfaceType = this.interfaceTypesInfoMap.get(type as Function);\n      if (interfaceType) {\n        this.usedInterfaceTypes.add(interfaceType.target);\n        gqlType = interfaceType.type;\n      }\n    }\n    if (!gqlType) {\n      const enumType = this.enumTypesInfoMap.get(type as object);\n      if (enumType) {\n        gqlType = enumType.type;\n      }\n    }\n    if (!gqlType) {\n      const unionType = this.unionTypesInfoMap.get(type as symbol);\n      if (unionType) {\n        gqlType = unionType.type;\n      }\n    }\n    if (!gqlType) {\n      throw new CannotDetermineGraphQLTypeError(\"output\", target.name, propertyName);\n    }\n\n    const { nullableByDefault } = BuildContext;\n    return wrapWithTypeOptions(target, propertyName, gqlType, typeOptions, nullableByDefault);\n  }\n\n  private static getGraphQLInputType(\n    target: Function,\n    propertyName: string,\n    type: TypeValue,\n    typeOptions: TypeOptions = {},\n    parameterIndex?: number,\n    argName?: string,\n  ): GraphQLInputType {\n    let gqlType: GraphQLInputType | undefined;\n    gqlType = convertTypeIfScalar(type);\n    if (!gqlType) {\n      const inputType = this.inputTypesInfoMap.get(type as Function);\n      if (inputType) {\n        gqlType = inputType.type;\n      }\n    }\n    if (!gqlType) {\n      const enumType = this.enumTypesInfoMap.get(type as object);\n      if (enumType) {\n        gqlType = enumType.type;\n      }\n    }\n    if (!gqlType) {\n      throw new CannotDetermineGraphQLTypeError(\n        \"input\",\n        target.name,\n        propertyName,\n        parameterIndex,\n        argName,\n      );\n    }\n\n    const { nullableByDefault } = BuildContext;\n    return wrapWithTypeOptions(target, propertyName, gqlType, typeOptions, nullableByDefault);\n  }\n\n  private static getResolveTypeFunction<TSource = any, TContext = any>(\n    resolveType: TypeResolver<TSource, TContext>,\n    possibleObjectTypesInfo: ObjectTypeInfo[],\n  ): GraphQLTypeResolver<TSource, TContext> {\n    return async (...args) => {\n      const resolvedType = await resolveType(...args);\n      if (!resolvedType || typeof resolvedType === \"string\") {\n        return resolvedType ?? undefined;\n      }\n      return possibleObjectTypesInfo.find(objectType => objectType.target === resolvedType)?.type\n        .name;\n    };\n  }\n\n  private static filterHandlersByResolvers<T extends ResolverMetadata>(\n    handlers: T[],\n    resolvers: Function[],\n  ) {\n    return handlers.filter(query => resolvers.includes(query.target));\n  }\n\n  private static filterTypesInfoByOrphanedTypesAndExtractType(\n    typesInfo: Array<ObjectTypeInfo | InterfaceTypeInfo | InputObjectTypeInfo>,\n    orphanedTypes: Function[],\n  ) {\n    return typesInfo.filter(it => orphanedTypes.includes(it.target)).map(it => it.type);\n  }\n}\n"
  },
  {
    "path": "src/schema/utils.ts",
    "content": "import {\n  type GraphQLFieldConfigArgumentMap,\n  type GraphQLFieldConfigMap,\n  type GraphQLInputFieldConfigMap,\n  type GraphQLInputObjectType,\n  type GraphQLInterfaceType,\n  type GraphQLObjectType,\n} from \"graphql\";\n\nexport function getFieldMetadataFromInputType(type: GraphQLInputObjectType) {\n  const fieldInfo = type.getFields();\n  const typeFields = Object.keys(fieldInfo).reduce<GraphQLInputFieldConfigMap>(\n    (fieldsMap, fieldName) => {\n      const superField = fieldInfo[fieldName];\n      // eslint-disable-next-line no-param-reassign\n      fieldsMap[fieldName] = {\n        type: superField.type,\n        astNode: superField.astNode,\n        description: superField.description,\n        defaultValue: superField.defaultValue,\n      };\n      return fieldsMap;\n    },\n    {},\n  );\n  return typeFields;\n}\n\nexport function getFieldMetadataFromObjectType(type: GraphQLObjectType | GraphQLInterfaceType) {\n  const fieldInfo = type.getFields();\n  const typeFields = Object.keys(fieldInfo).reduce<GraphQLFieldConfigMap<any, any>>(\n    (fieldsMap, fieldName) => {\n      const superField = fieldInfo[fieldName];\n      // eslint-disable-next-line no-param-reassign\n      fieldsMap[fieldName] = {\n        type: superField.type,\n        args: superField.args.reduce<GraphQLFieldConfigArgumentMap>((argMap, { name, ...arg }) => {\n          // eslint-disable-next-line no-param-reassign\n          argMap[name] = arg;\n          return argMap;\n        }, {}),\n        astNode: superField.astNode,\n        resolve: superField.resolve,\n        description: superField.description,\n        deprecationReason: superField.deprecationReason,\n        extensions: superField.extensions,\n      };\n      return fieldsMap;\n    },\n    {},\n  );\n  return typeFields;\n}\n"
  },
  {
    "path": "src/shim.ts",
    "content": "/*\n  This \"shim\" can be used on the frontend to prevent from errors on undefined decorators,\n  when you are sharing same classes across backend and frontend.\n\n  To use this shim, simply set up your Webpack configuration\n  to use this file instead of a normal TypeGraphQL module.\n\n  ```js\n  plugins: [\n    // ...here are any other existing plugins that you already have\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/shim\");\n    }),\n  ]\n  ```\n\n  However, in some TypeScript projects like the ones using Angular,\n  which AoT compiler requires that a full `*.ts` file is provided\n  instead of just a `*.js` and `*.d.ts` files, to use this shim\n  we have to simply set up our TypeScript configuration in `tsconfig.json`\n  to use this file instead of a normal TypeGraphQL module:\n\n  ```json\n  {\n    \"compilerOptions\": {\n      \"baseUrl\": \".\",\n      \"paths\": {\n        \"type-graphql\": [\"./node_modules/type-graphql/build/typings/shim.ts\"]\n      }\n    }\n  }\n  ```\n*/\n\nimport type * as src from \"./index\";\n\nexport const dummyValue = \"\";\nexport function dummyFn() {}\nexport function dummyDecorator() {\n  return dummyFn;\n}\n\nexport const Arg: typeof src.Arg = dummyDecorator;\nexport const Args: typeof src.Args = dummyDecorator;\nexport const ArgsType: typeof src.ArgsType = dummyDecorator;\nexport const Authorized: typeof src.Authorized = dummyDecorator;\nexport const createParameterDecorator: typeof src.createParameterDecorator = dummyFn as any;\nexport const createMethodMiddlewareDecorator: typeof src.createMethodMiddlewareDecorator =\n  dummyFn as any;\nexport const createResolverClassMiddlewareDecorator: typeof src.createResolverClassMiddlewareDecorator =\n  dummyFn as any;\nexport const Ctx: typeof src.Ctx = dummyDecorator;\nexport const Directive: typeof src.Directive = dummyDecorator;\nexport const Extensions: typeof src.Extensions = dummyDecorator;\nexport const registerEnumType: typeof src.registerEnumType = dummyFn;\nexport const Field: typeof src.Field = dummyDecorator;\nexport const FieldResolver: typeof src.FieldResolver = dummyDecorator;\nexport const Info: typeof src.Info = dummyDecorator;\nexport const InputType: typeof src.InputType = dummyDecorator;\nexport const InterfaceType: typeof src.InterfaceType = dummyDecorator;\nexport const Mutation: typeof src.Mutation = dummyDecorator;\nexport const ObjectType: typeof src.ObjectType = dummyDecorator;\nexport const Query: typeof src.Query = dummyDecorator;\nexport const Resolver: typeof src.Resolver = dummyDecorator;\nexport const Root: typeof src.Root = dummyDecorator;\nexport const Subscription: typeof src.Subscription = dummyDecorator;\nexport const createUnionType: typeof src.createUnionType = dummyFn as any;\nexport const UseMiddleware: typeof src.UseMiddleware = dummyDecorator;\n\nexport const Int: typeof src.Int = dummyValue as any;\nexport const Float: typeof src.Float = dummyValue as any;\nexport const ID: typeof src.ID = dummyValue as any;\nexport const GraphQLISODateTime: typeof src.GraphQLISODateTime = dummyValue as any;\nexport const GraphQLTimestamp: typeof src.GraphQLTimestamp = dummyValue as any;\n"
  },
  {
    "path": "src/typings/Complexity.ts",
    "content": "import { type ComplexityEstimator } from \"graphql-query-complexity\";\n\nexport type Complexity = ComplexityEstimator | number;\n"
  },
  {
    "path": "src/typings/ResolverInterface.ts",
    "content": "/**\n * Resolver classes can implement this type\n * to provide a proper resolver method signatures for fields of T.\n */\nexport type ResolverInterface<T extends object> = {\n  [P in keyof T]?: (root: T, ...args: any[]) => T[P] | Promise<T[P]>;\n};\n"
  },
  {
    "path": "src/typings/SubscribeResolverData.ts",
    "content": "import { type GraphQLResolveInfo } from \"graphql\";\nimport { type ArgsDictionary } from \"./resolver-data\";\n\nexport interface SubscribeResolverData<TSource = any, TArgs = ArgsDictionary, TContext = {}> {\n  source: TSource;\n  args: TArgs;\n  context: TContext;\n  info: GraphQLResolveInfo;\n}\n"
  },
  {
    "path": "src/typings/SubscriptionHandlerData.ts",
    "content": "import { type GraphQLResolveInfo } from \"graphql\";\nimport { type ArgsDictionary } from \"./resolver-data\";\n\nexport interface SubscriptionHandlerData<TPayload = any, TArgs = ArgsDictionary, TContext = {}> {\n  payload: TPayload;\n  args: TArgs;\n  context: TContext;\n  info: GraphQLResolveInfo;\n}\n"
  },
  {
    "path": "src/typings/TypeResolver.ts",
    "content": "import { type GraphQLTypeResolver } from \"graphql\";\nimport { type ClassType, type Maybe, type MaybePromise } from \"./utils\";\n\nexport type TypeResolver<TSource, TContext> = (\n  ...args: Parameters<GraphQLTypeResolver<TSource, TContext>>\n) => MaybePromise<Maybe<string | ClassType>>;\n"
  },
  {
    "path": "src/typings/ValidatorFn.ts",
    "content": "import { type TypeValue } from \"@/decorators/types\";\nimport { type ResolverData } from \"./resolver-data\";\n\nexport type ValidatorFn<TContext extends object = object> = (\n  /**\n   * The value of the argument.\n   * It can by of any type, which means:\n   * - undefined or null (if the argument is nullable)\n   * - primitive type (string, number, boolean)\n   * - underlying scalar type (Date, Buffer, etc.)\n   * - object type (arg type class instance)\n   * - array type (array of any of the above)\n   */\n  argValue: any | undefined,\n  argType: TypeValue,\n  resolverData: ResolverData<TContext>,\n) => void | Promise<void>;\n"
  },
  {
    "path": "src/typings/auth-checker.ts",
    "content": "import { type ResolverData } from \"./resolver-data\";\nimport { type ClassType } from \"./utils\";\n\nexport type AuthCheckerFn<TContextType extends object = object, TRoleType = string> = (\n  resolverData: ResolverData<TContextType>,\n  roles: TRoleType[],\n) => boolean | Promise<boolean>;\n\nexport interface AuthCheckerInterface<TContextType extends object = object, TRoleType = string> {\n  check(resolverData: ResolverData<TContextType>, roles: TRoleType[]): boolean | Promise<boolean>;\n}\n\nexport type AuthChecker<TContextType extends object = object, TRoleType = string> =\n  | AuthCheckerFn<TContextType, TRoleType>\n  | ClassType<AuthCheckerInterface<TContextType, TRoleType>>;\n\nexport type AuthMode = \"error\" | \"null\";\n"
  },
  {
    "path": "src/typings/index.ts",
    "content": "export * from \"./utils\";\nexport * from \"./auth-checker\";\nexport * from \"./Complexity\";\nexport * from \"./legacy-decorators\";\nexport type { MiddlewareFn, NextFn, MiddlewareInterface } from \"./middleware\";\nexport * from \"./resolver-data\";\nexport * from \"./ResolverInterface\";\nexport * from \"./resolvers-map\";\nexport * from \"./SubscribeResolverData\";\nexport * from \"./SubscriptionHandlerData\";\nexport * from \"./subscriptions\";\nexport * from \"./TypeResolver\";\nexport * from \"./ValidatorFn\";\n"
  },
  {
    "path": "src/typings/legacy-decorators.ts",
    "content": "export type ParameterDecorator = (\n  target: Object,\n  propertyKey: string | symbol, // Removed 'undefined' from TS 5.0\n  parameterIndex: number,\n) => void;\n"
  },
  {
    "path": "src/typings/middleware.ts",
    "content": "import { type ResolverData } from \"./resolver-data\";\n\nexport type NextFn = () => Promise<any>;\n\nexport type MiddlewareFn<TContext extends object = object> = (\n  action: ResolverData<TContext>,\n  next: NextFn,\n) => Promise<any>;\n\nexport interface MiddlewareInterface<TContext extends object = object> {\n  use: MiddlewareFn<TContext>;\n}\nexport type MiddlewareClass<TContext extends object = object> = new (\n  ...args: any[]\n) => MiddlewareInterface<TContext>;\n\nexport type Middleware<TContext extends object = object> =\n  | MiddlewareFn<TContext>\n  | MiddlewareClass<TContext>;\n"
  },
  {
    "path": "src/typings/resolver-data.ts",
    "content": "import { type GraphQLResolveInfo } from \"graphql\";\n\nexport type ArgsDictionary = Record<string, any>;\n\nexport interface ResolverData<TContextType extends object = object> {\n  root: any;\n  args: ArgsDictionary;\n  context: TContextType;\n  info: GraphQLResolveInfo;\n}\n"
  },
  {
    "path": "src/typings/resolvers-map.ts",
    "content": "import {\n  type GraphQLFieldResolver,\n  type GraphQLIsTypeOfFn,\n  type GraphQLScalarType,\n  type GraphQLTypeResolver,\n} from \"graphql\";\n\nexport type ResolversMap<TSource = any, TContext = any> = Record<\n  string,\n  | ResolverObject<TSource, TContext>\n  | ResolverOptions<TSource, TContext>\n  | GraphQLScalarType\n  | EnumResolver\n>;\n\nexport type ResolverObject<TSource = any, TContext = any> = Record<\n  string,\n  ResolverOptions<TSource, TContext> | GraphQLFieldResolver<TSource, TContext>\n>;\n\nexport type EnumResolver = Record<string, string | number>;\n\nexport interface ResolverOptions<TSource = any, TContext = any> {\n  fragment?: string;\n  resolve?: GraphQLFieldResolver<TSource, TContext>;\n  subscribe?: GraphQLFieldResolver<TSource, TContext>;\n  __resolveType?: GraphQLTypeResolver<TSource, TContext>;\n  __isTypeOf?: GraphQLIsTypeOfFn<TSource, TContext>;\n}\n"
  },
  {
    "path": "src/typings/subscriptions.ts",
    "content": "export interface PubSub {\n  /**\n   * Publish a value for a given topic.\n   */\n  publish(routingKey: string, ...args: unknown[]): void;\n  /**\n   * Subscribe to a topic.\n   */\n  subscribe(routingKey: string, dynamicId?: unknown): AsyncIterable<unknown>;\n}\n"
  },
  {
    "path": "src/typings/utils/ClassType.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/basic.d.ts)\n\nimport { type Constructor } from \"./Constructor\";\n\n/**\nMatches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).\n*/\nexport type ClassType<T extends object = object, Arguments extends unknown[] = any[]> = Constructor<\n  T,\n  Arguments\n> & {\n  prototype: T;\n};\n"
  },
  {
    "path": "src/typings/utils/Constructor.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/basic.d.ts)\n\n/**\nMatches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).\n*/\nexport type Constructor<T extends object, Arguments extends unknown[] = any[]> = new (\n  ...arguments_: Arguments\n) => T;\n"
  },
  {
    "path": "src/typings/utils/Except.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/except.d.ts)\n\nimport { type IsEqual } from \"./IsEqual\";\n\n/**\nFilter out keys from an object.\n\nReturns `never` if `Exclude` is strictly equal to `Key`.\nReturns `never` if `Key` extends `Exclude`.\nReturns `Key` otherwise.\n\n@example\n```\ntype Filtered = Filter<'foo', 'foo'>;\n//=> never\n```\n\n@example\n```\ntype Filtered = Filter<'bar', string>;\n//=> never\n```\n\n@example\n```\ntype Filtered = Filter<'bar', 'foo'>;\n//=> 'bar'\n```\n*/\ntype Filter<KeyType, ExcludeType> =\n  IsEqual<KeyType, ExcludeType> extends true\n    ? never\n    : KeyType extends ExcludeType\n      ? never\n      : KeyType;\n\ninterface ExceptOptions {\n  /**\n\tDisallow assigning non-specified properties.\n\n\tNote that any omitted properties in the resulting type will be present in autocomplete as `undefined`.\n\n\t@defaultValue false\n\t*/\n  requireExactProps?: boolean;\n}\n\n/**\nCreate a type from an object type without certain keys.\n\nWe recommend setting the `requireExactProps` option to `true`.\n\nThis 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.\n\nThis 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)).\n\n@example\n```\nimport {Except} from 'type-fest';\n\ntype Foo = {\n\ta: number;\n\tb: string;\n};\n\ntype FooWithoutA = Except<Foo, 'a'>;\n//=> {b: string}\n\nconst fooWithoutA: FooWithoutA = {a: 1, b: '2'};\n//=> errors: 'a' does not exist in type '{ b: string; }'\n\ntype FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;\n//=> {a: number} & Partial<Record<\"b\", never>>\n\nconst fooWithoutB: FooWithoutB = {a: 1, b: '2'};\n//=> errors at 'b': Type 'string' is not assignable to type 'undefined'.\n```\n*/\nexport type Except<\n  ObjectType,\n  KeysType extends keyof ObjectType,\n  Options extends ExceptOptions = { requireExactProps: false },\n> = {\n  [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];\n} & (Options[\"requireExactProps\"] extends true ? Partial<Record<KeysType, never>> : {});\n"
  },
  {
    "path": "src/typings/utils/IsEqual.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/is-equal.d.ts)\n\n/**\nReturns a boolean for whether the two given types are equal.\n\n{@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650}\n{@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796}\n\nUse-cases:\n- If you want to make a conditional branch based on the result of a comparison of two types.\n\n@example\n```\nimport {IsEqual} from 'type-fest';\n\n// This type returns a boolean for whether the given array includes the given item.\n// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.\ntype Includes<Value extends readonly any[], Item> =\n\tValue extends readonly [Value[0], ...infer rest]\n\t\t? IsEqual<Value[0], Item> extends true\n\t\t\t? true\n\t\t\t: Includes<rest, Item>\n\t\t: false;\n```\n*/\nexport type IsEqual<A, B> =\n  (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2 ? true : false;\n"
  },
  {
    "path": "src/typings/utils/Maybe.ts",
    "content": "export type Maybe<T> = T | null | undefined;\n"
  },
  {
    "path": "src/typings/utils/MaybePromise.ts",
    "content": "export type MaybePromise<T> = Promise<T> | T;\n"
  },
  {
    "path": "src/typings/utils/MergeExclusive.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/merge-exclusive.d.ts)\n\n// Helper type. Not useful on its own.\ntype Without<FirstType, SecondType> = {\n  [KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never;\n};\n\n/**\nCreate a type that has mutually exclusive keys.\n\nThis type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604).\n\nThis type works with a helper type, called `Without`. `Without<FirstType, SecondType>` 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`.\n\n@example\n```\nimport {MergeExclusive} from 'type-fest';\n\ninterface ExclusiveVariation1 {\n\texclusive1: boolean;\n}\n\ninterface ExclusiveVariation2 {\n\texclusive2: string;\n}\n\ntype ExclusiveOptions = MergeExclusive<ExclusiveVariation1, ExclusiveVariation2>;\n\nlet exclusiveOptions: ExclusiveOptions;\n\nexclusiveOptions = {exclusive1: true};\n//=> Works\nexclusiveOptions = {exclusive2: 'hi'};\n//=> Works\nexclusiveOptions = {exclusive1: true, exclusive2: 'hi'};\n//=> Error\n```\n*/\nexport type MergeExclusive<FirstType, SecondType> = FirstType | SecondType extends object\n  ? (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType)\n  : FirstType | SecondType;\n"
  },
  {
    "path": "src/typings/utils/NonEmptyArray.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/set-required.d.ts)\n\nexport type NonEmptyArray<T> = readonly [T, ...T[]] | [T, ...T[]];\n"
  },
  {
    "path": "src/typings/utils/SetRequired.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/set-required.d.ts)\n\nimport { type Except } from \"./Except\";\nimport { type Simplify } from \"./Simplify\";\n\n/**\nCreate a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.\n\nUse-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.\n\n@example\n```\nimport {SetRequired} from 'type-fest';\n\ntype Foo = {\n\ta?: number;\n\tb: string;\n\tc?: boolean;\n}\n\ntype SomeRequired = SetRequired<Foo, 'b' | 'c'>;\n// type SomeRequired = {\n// \ta?: number;\n// \tb: string; // Was already required and still is.\n// \tc: boolean; // Is now required.\n// }\n```\n*/\nexport type SetRequired<BaseType, Keys extends keyof BaseType> = Simplify<\n  // Pick just the keys that are optional from the base type.\n  Except<BaseType, Keys> &\n    // Pick the keys that should be required from the base type and make them required.\n    Required<Pick<BaseType, Keys>>\n>;\n"
  },
  {
    "path": "src/typings/utils/Simplify.ts",
    "content": "// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts)\n\n/**\nUseful 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.\n\n@example\n```\nimport {Simplify} from 'type-fest';\n\ntype PositionProps = {\n\ttop: number;\n\tleft: number;\n};\n\ntype SizeProps = {\n\twidth: number;\n\theight: number;\n};\n\n// In your editor, hovering over `Props` will show a flattened object with all the properties.\ntype Props = Simplify<PositionProps & SizeProps>;\n```\n\nSometimes 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<string, unknown>`. 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.\n\nIf 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<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument.  Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.\n\n@example\n```\nimport {Simplify} from 'type-fest';\n\ninterface SomeInterface {\n\tfoo: number;\n\tbar?: string;\n\tbaz: number | undefined;\n}\n\ntype SomeType = {\n\tfoo: number;\n\tbar?: string;\n\tbaz: number | undefined;\n};\n\nconst literal = {foo: 123, bar: 'hello', baz: 456};\nconst someType: SomeType = literal;\nconst someInterface: SomeInterface = literal;\n\nfunction fn(object: Record<string, unknown>): void {}\n\nfn(literal); // Good: literal object type is sealed\nfn(someType); // Good: type is sealed\nfn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened\nfn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`\n```\n\n{@link https://github.com/microsoft/TypeScript/issues/15300}\n*/\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\n"
  },
  {
    "path": "src/typings/utils/index.ts",
    "content": "export * from \"./ClassType\";\nexport * from \"./Constructor\";\nexport * from \"./Except\";\nexport * from \"./IsEqual\";\nexport * from \"./Maybe\";\nexport * from \"./MaybePromise\";\nexport * from \"./MergeExclusive\";\nexport * from \"./NonEmptyArray\";\nexport * from \"./SetRequired\";\nexport * from \"./Simplify\";\n"
  },
  {
    "path": "src/utils/buildSchema.ts",
    "content": "import path from \"node:path\";\nimport { type GraphQLSchema } from \"graphql\";\nimport { SchemaGenerator, type SchemaGeneratorOptions } from \"@/schema/schema-generator\";\nimport { type NonEmptyArray } from \"@/typings\";\nimport {\n  type PrintSchemaOptions,\n  defaultPrintSchemaOptions,\n  emitSchemaDefinitionFile,\n  emitSchemaDefinitionFileSync,\n} from \"./emitSchemaDefinitionFile\";\n\ntype EmitSchemaFileOptions = {\n  path?: string;\n} & Partial<PrintSchemaOptions>;\n\nfunction getEmitSchemaDefinitionFileOptions(buildSchemaOptions: BuildSchemaOptions): {\n  schemaFileName: string;\n  printSchemaOptions: PrintSchemaOptions;\n} {\n  const defaultSchemaFilePath = path.resolve(process.cwd(), \"schema.graphql\");\n\n  return {\n    schemaFileName:\n      // eslint-disable-next-line no-nested-ternary\n      typeof buildSchemaOptions.emitSchemaFile === \"string\"\n        ? buildSchemaOptions.emitSchemaFile\n        : typeof buildSchemaOptions.emitSchemaFile === \"object\"\n          ? buildSchemaOptions.emitSchemaFile.path || defaultSchemaFilePath\n          : defaultSchemaFilePath,\n    printSchemaOptions:\n      typeof buildSchemaOptions.emitSchemaFile === \"object\"\n        ? { ...defaultPrintSchemaOptions, ...buildSchemaOptions.emitSchemaFile }\n        : defaultPrintSchemaOptions,\n  };\n}\n\nfunction loadResolvers(options: BuildSchemaOptions): Function[] {\n  // Additional runtime check as it should be covered by the `NonEmptyArray` type guard\n  if (options.resolvers.length === 0) {\n    throw new Error(\"Empty `resolvers` array property found in `buildSchema` options!\");\n  }\n\n  return options.resolvers as Function[];\n}\n\nexport type BuildSchemaOptions = {\n  /** Array of resolvers classes to resolver files */\n  resolvers: NonEmptyArray<Function>;\n  /**\n   * Path to the file to where emit the schema\n   * or config object with print schema options\n   * or `true` for the default `./schema.graphql` one\n   */\n  emitSchemaFile?: string | boolean | EmitSchemaFileOptions;\n} & Omit<SchemaGeneratorOptions, \"resolvers\">;\n\nexport async function buildSchema(options: BuildSchemaOptions): Promise<GraphQLSchema> {\n  const resolvers = loadResolvers(options);\n  const schema = SchemaGenerator.generateFromMetadata({ ...options, resolvers });\n  if (options.emitSchemaFile) {\n    const { schemaFileName, printSchemaOptions } = getEmitSchemaDefinitionFileOptions(options);\n    await emitSchemaDefinitionFile(schemaFileName, schema, printSchemaOptions);\n  }\n\n  return schema;\n}\n\nexport function buildSchemaSync(options: BuildSchemaOptions): GraphQLSchema {\n  const resolvers = loadResolvers(options);\n  const schema = SchemaGenerator.generateFromMetadata({ ...options, resolvers });\n  if (options.emitSchemaFile) {\n    const { schemaFileName, printSchemaOptions } = getEmitSchemaDefinitionFileOptions(options);\n    emitSchemaDefinitionFileSync(schemaFileName, schema, printSchemaOptions);\n  }\n\n  return schema;\n}\n"
  },
  {
    "path": "src/utils/buildTypeDefsAndResolvers.ts",
    "content": "import { type GraphQLSchema, printSchema } from \"graphql\";\nimport { type BuildSchemaOptions, buildSchema, buildSchemaSync } from \"./buildSchema\";\nimport { createResolversMap } from \"./createResolversMap\";\n\nfunction createTypeDefsAndResolversMap(schema: GraphQLSchema) {\n  const typeDefs = printSchema(schema);\n  const resolvers = createResolversMap(schema);\n  return { typeDefs, resolvers };\n}\n\nexport async function buildTypeDefsAndResolvers(options: BuildSchemaOptions) {\n  const schema = await buildSchema(options);\n  return createTypeDefsAndResolversMap(schema);\n}\n\nexport function buildTypeDefsAndResolversSync(options: BuildSchemaOptions) {\n  const schema = buildSchemaSync(options);\n  return createTypeDefsAndResolversMap(schema);\n}\n"
  },
  {
    "path": "src/utils/container.ts",
    "content": "/* eslint-disable max-classes-per-file */\nimport { type ResolverData } from \"@/typings\";\n\nexport type SupportedType<T> = (new (...args: any[]) => T) | Function;\n\nexport interface ContainerType {\n  get(someClass: any, resolverData: ResolverData<any>): any | Promise<any>;\n}\n\nexport type ContainerGetter<TContext extends object> = (\n  resolverData: ResolverData<TContext>,\n) => ContainerType;\n\n/**\n * Container to be used by this library for inversion control.\n * If container was not implicitly set then by default\n * container simply creates a new instance of the given class.\n */\nclass DefaultContainer {\n  private instances: Array<{ type: Function; object: any }> = [];\n\n  get<T>(someClass: SupportedType<T>): T {\n    let instance = this.instances.find(it => it.type === someClass);\n    if (!instance) {\n      instance = { type: someClass, object: new (someClass as any)() };\n      this.instances.push(instance);\n    }\n\n    return instance.object;\n  }\n}\n\nexport class IOCContainer {\n  private container: ContainerType | undefined;\n\n  private containerGetter: ContainerGetter<any> | undefined;\n\n  private defaultContainer = new DefaultContainer();\n\n  constructor(iocContainerOrContainerGetter?: ContainerType | ContainerGetter<any>) {\n    if (\n      iocContainerOrContainerGetter &&\n      \"get\" in iocContainerOrContainerGetter &&\n      typeof iocContainerOrContainerGetter.get === \"function\"\n    ) {\n      this.container = iocContainerOrContainerGetter;\n    } else if (typeof iocContainerOrContainerGetter === \"function\") {\n      this.containerGetter = iocContainerOrContainerGetter;\n    }\n  }\n\n  getInstance<T = any>(\n    someClass: SupportedType<T>,\n    resolverData: ResolverData<any>,\n  ): T | Promise<T> {\n    const container = this.containerGetter ? this.containerGetter(resolverData) : this.container;\n    if (!container) {\n      return this.defaultContainer.get<T>(someClass);\n    }\n    return container.get(someClass, resolverData);\n  }\n}\n"
  },
  {
    "path": "src/utils/createResolversMap.ts",
    "content": "/* eslint-disable no-param-reassign */\nimport {\n  type GraphQLAbstractType,\n  GraphQLEnumType,\n  type GraphQLFieldMap,\n  GraphQLInterfaceType,\n  GraphQLObjectType,\n  GraphQLScalarType,\n  type GraphQLSchema,\n  type GraphQLTypeResolver,\n  GraphQLUnionType,\n} from \"graphql\";\nimport { type EnumResolver, type ResolverObject, type ResolversMap } from \"@/typings\";\n\nfunction generateTypeResolver(\n  abstractType: GraphQLAbstractType,\n  schema: GraphQLSchema,\n): GraphQLTypeResolver<any, any> {\n  if (abstractType.resolveType) {\n    return abstractType.resolveType;\n  }\n\n  const possibleObjectTypes = schema.getPossibleTypes(abstractType);\n  return async (source, context, info) => {\n    for (const objectType of possibleObjectTypes) {\n      // eslint-disable-next-line no-await-in-loop\n      if (objectType.isTypeOf && (await objectType.isTypeOf(source, context, info))) {\n        return objectType.name;\n      }\n    }\n    return undefined;\n  };\n}\n\nfunction generateFieldsResolvers(fields: GraphQLFieldMap<any, any>): ResolverObject {\n  return Object.keys(fields).reduce<ResolverObject>((fieldsMap, fieldName) => {\n    const field = fields[fieldName];\n    if (field.subscribe) {\n      fieldsMap[fieldName] = {\n        subscribe: field.subscribe,\n        resolve: field.resolve,\n      };\n    } else if (field.resolve) {\n      fieldsMap[fieldName] = field.resolve;\n    }\n    return fieldsMap;\n  }, {});\n}\n\nexport function createResolversMap(schema: GraphQLSchema): ResolversMap {\n  const typeMap = schema.getTypeMap();\n  return Object.keys(typeMap)\n    .filter(typeName => !typeName.startsWith(\"__\"))\n    .reduce<ResolversMap>((resolversMap, typeName) => {\n      const type = typeMap[typeName];\n      if (type instanceof GraphQLObjectType) {\n        resolversMap[typeName] = {\n          ...(type.isTypeOf && {\n            __isTypeOf: type.isTypeOf,\n          }),\n          ...generateFieldsResolvers(type.getFields()),\n        };\n      }\n      if (type instanceof GraphQLInterfaceType) {\n        resolversMap[typeName] = {\n          __resolveType: generateTypeResolver(type, schema),\n          ...generateFieldsResolvers(type.getFields()),\n        };\n      }\n      if (type instanceof GraphQLScalarType) {\n        resolversMap[typeName] = type;\n      }\n      if (type instanceof GraphQLEnumType) {\n        const enumValues = type.getValues();\n        resolversMap[typeName] = enumValues.reduce<EnumResolver>((enumMap, { name, value }) => {\n          enumMap[name] = value;\n          return enumMap;\n        }, {});\n      }\n      if (type instanceof GraphQLUnionType) {\n        resolversMap[typeName] = {\n          __resolveType: generateTypeResolver(type, schema),\n        };\n      }\n      return resolversMap;\n    }, {});\n}\n"
  },
  {
    "path": "src/utils/emitSchemaDefinitionFile.ts",
    "content": "import { type GraphQLSchema, lexicographicSortSchema, printSchema } from \"graphql\";\nimport { outputFile, outputFileSync } from \"@/helpers/filesystem\";\n\nexport interface PrintSchemaOptions {\n  sortedSchema: boolean;\n}\n\nexport const defaultPrintSchemaOptions: PrintSchemaOptions = {\n  sortedSchema: true,\n};\n\nconst generatedSchemaWarning = /* graphql */ `\\\n# -----------------------------------------------\n# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!\n# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!\n# -----------------------------------------------\n\n`;\n\nfunction getSchemaFileContent(schema: GraphQLSchema, options: PrintSchemaOptions) {\n  const schemaToEmit = options.sortedSchema ? lexicographicSortSchema(schema) : schema;\n  return generatedSchemaWarning + printSchema(schemaToEmit);\n}\n\nexport function emitSchemaDefinitionFileSync(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n  options: PrintSchemaOptions = defaultPrintSchemaOptions,\n) {\n  const schemaFileContent = getSchemaFileContent(schema, options);\n  outputFileSync(schemaFilePath, schemaFileContent);\n}\n\nexport async function emitSchemaDefinitionFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n  options: PrintSchemaOptions = defaultPrintSchemaOptions,\n) {\n  const schemaFileContent = getSchemaFileContent(schema, options);\n  await outputFile(schemaFilePath, schemaFileContent);\n}\n"
  },
  {
    "path": "src/utils/graphql-version.ts",
    "content": "import * as graphql from \"graphql\";\nimport semVer from \"semver\";\n// Avoid '@/' due to 'scripts/version.ts'\nimport { UnmetGraphQLPeerDependencyError } from \"../errors\";\n\n// This must be kept in sync with 'package.json'\nexport const graphQLPeerDependencyVersion = \"^16.12.0\";\n\nexport function ensureInstalledCorrectGraphQLPackage() {\n  if (!semVer.satisfies(graphql.version, graphQLPeerDependencyVersion)) {\n    throw new UnmetGraphQLPeerDependencyError(graphql.version, graphQLPeerDependencyVersion);\n  }\n}\n"
  },
  {
    "path": "src/utils/index.ts",
    "content": "export type { BuildSchemaOptions } from \"./buildSchema\";\nexport { buildSchema, buildSchemaSync } from \"./buildSchema\";\nexport {\n  buildTypeDefsAndResolvers,\n  buildTypeDefsAndResolversSync,\n} from \"./buildTypeDefsAndResolvers\";\nexport type { ContainerType, ContainerGetter } from \"./container\";\nexport { createResolversMap } from \"./createResolversMap\";\nexport type { PrintSchemaOptions } from \"./emitSchemaDefinitionFile\";\nexport {\n  emitSchemaDefinitionFile,\n  emitSchemaDefinitionFileSync,\n  defaultPrintSchemaOptions,\n} from \"./emitSchemaDefinitionFile\";\nexport * from \"./graphql-version\";\n"
  },
  {
    "path": "src/utils/isPromiseLike.ts",
    "content": "export function isPromiseLike<TValue>(\n  value: PromiseLike<TValue> | TValue,\n): value is PromiseLike<TValue> {\n  return value != null && typeof (value as PromiseLike<TValue>).then === \"function\";\n}\n"
  },
  {
    "path": "tests/.eslintrc",
    "content": "{\n  \"env\": {\n    \"jest/globals\": true\n  },\n  \"rules\": {\n    \"max-classes-per-file\": \"off\",\n    \"class-methods-use-this\": \"off\",\n    \"import/no-extraneous-dependencies\": [\n      \"error\",\n      {\n        \"devDependencies\": true\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "tests/functional/authorization.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, graphql } from \"graphql\";\nimport {\n  type AuthCheckerInterface,\n  AuthenticationError,\n  AuthorizationError,\n  Authorized,\n  Ctx,\n  Field,\n  FieldResolver,\n  ObjectType,\n  Query,\n  Resolver,\n  type ResolverData,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\n\ndescribe(\"Authorization\", () => {\n  let schema: GraphQLSchema;\n  let sampleResolver: any;\n\n  beforeEach(async () => {\n    getMetadataStorage().clear();\n\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      normalField!: string;\n\n      @Field()\n      @Authorized()\n      authedField!: string;\n\n      @Field({ nullable: true })\n      @Authorized()\n      nullableAuthedField!: string;\n\n      @Field()\n      @Authorized(\"ADMIN\")\n      adminField!: string;\n\n      @Field()\n      normalResolvedField!: string;\n\n      @Field()\n      authedResolvedField!: string;\n\n      @Field()\n      @Authorized()\n      inlineAuthedResolvedField!: string;\n    }\n\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      @Query()\n      normalQuery(): boolean {\n        return true;\n      }\n\n      @Query()\n      normalObjectQuery(): SampleObject {\n        return {\n          normalField: \"normalField\",\n          authedField: \"authedField\",\n          adminField: \"adminField\",\n        } as SampleObject;\n      }\n\n      @Query()\n      @Authorized()\n      authedQuery(@Ctx() ctx: any): boolean {\n        return ctx.user !== undefined;\n      }\n\n      @Query(() => Boolean, { nullable: true })\n      @Authorized()\n      nullableAuthedQuery() {\n        return true;\n      }\n\n      @Query()\n      @Authorized(\"ADMIN\")\n      adminQuery(@Ctx() ctx: any): boolean {\n        return ctx.user !== undefined;\n      }\n\n      @Query()\n      @Authorized([\"ADMIN\", \"REGULAR\"])\n      adminOrRegularQuery(@Ctx() ctx: any): boolean {\n        return ctx.user !== undefined;\n      }\n\n      @Query()\n      @Authorized(\"ADMIN\", \"REGULAR\")\n      adminOrRegularRestQuery(@Ctx() ctx: any): boolean {\n        return ctx.user !== undefined;\n      }\n\n      @FieldResolver()\n      normalResolvedField() {\n        return \"normalResolvedField\";\n      }\n\n      @FieldResolver()\n      @Authorized()\n      authedResolvedField() {\n        return \"authedResolvedField\";\n      }\n\n      @FieldResolver()\n      inlineAuthedResolvedField() {\n        return \"inlineAuthedResolvedField\";\n      }\n    }\n\n    sampleResolver = SampleResolver;\n    schema = await buildSchema({\n      resolvers: [SampleResolver],\n      // dummy auth checker\n      authChecker: () => false,\n    });\n  });\n\n  describe(\"Reflection\", () => {\n    // helpers\n    function findQuery(queryName: string) {\n      return getMetadataStorage().queries.find(it => it.methodName === queryName)!;\n    }\n\n    it(\"should build schema without errors\", async () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should register correct roles for resolvers\", async () => {\n      const normalQuery = findQuery(\"normalQuery\");\n      const authedQuery = findQuery(\"authedQuery\");\n      const adminQuery = findQuery(\"adminQuery\");\n\n      expect(normalQuery.roles).toBeUndefined();\n      expect(authedQuery.roles).toHaveLength(0);\n      expect(adminQuery.roles).toHaveLength(1);\n    });\n\n    it(\"should register correct roles for object type fields\", async () => {\n      const sampleObject = getMetadataStorage().objectTypes.find(\n        type => type.name === \"SampleObject\",\n      )!;\n      const normalField = sampleObject.fields!.find(field => field.name === \"normalField\")!;\n      const authedField = sampleObject.fields!.find(field => field.name === \"authedField\")!;\n      const adminField = sampleObject.fields!.find(field => field.name === \"adminField\")!;\n\n      expect(normalField.roles).toBeUndefined();\n      expect(authedField.roles).toHaveLength(0);\n      expect(adminField.roles).toEqual([\"ADMIN\"]);\n    });\n\n    it(\"should register correct roles for every decorator overload\", async () => {\n      const normalQuery = findQuery(\"normalQuery\");\n      const authedQuery = findQuery(\"authedQuery\");\n      const adminQuery = findQuery(\"adminQuery\");\n      const adminOrRegularQuery = findQuery(\"adminOrRegularQuery\");\n      const adminOrRegularRestQuery = findQuery(\"adminOrRegularRestQuery\");\n\n      expect(normalQuery.roles).toBeUndefined();\n      expect(authedQuery.roles).toHaveLength(0);\n      expect(adminQuery.roles).toEqual([\"ADMIN\"]);\n      expect(adminOrRegularQuery.roles).toEqual([\"ADMIN\", \"REGULAR\"]);\n      expect(adminOrRegularRestQuery.roles).toEqual([\"ADMIN\", \"REGULAR\"]);\n    });\n  });\n\n  describe(\"Errors\", () => {\n    it(\"should throw error when `@Authorized` is used and no `authChecker` provided\", async () => {\n      const error = await expectToThrow(() =>\n        buildSchema({\n          resolvers: [sampleResolver],\n        }),\n      );\n\n      expect(error).toBeDefined();\n      expect(error.message).toContain(\"authChecker\");\n    });\n\n    // TODO: check for wrong `@Authorized` usage\n    it.todo(\"should throw error when `@Authorized` is used on args, input or interface class\");\n  });\n\n  describe(\"Functional\", () => {\n    it(\"should allow to register auth checker\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => true,\n      });\n\n      expect(localSchema).toBeDefined();\n    });\n\n    it(\"should allow to read not guarded query\", async () => {\n      const query = `query {\n        normalQuery\n      }`;\n\n      const result: any = await graphql({ schema, source: query, contextValue: {} });\n\n      expect(result.data!.normalQuery).toEqual(true);\n    });\n\n    it(\"should allow to read not guarded object field\", async () => {\n      const query = `query {\n        normalObjectQuery {\n          normalField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query, contextValue: {} });\n\n      expect(result.data!.normalObjectQuery.normalField).toEqual(\"normalField\");\n    });\n\n    it(\"should allow to read not guarded object field from resolver\", async () => {\n      const query = `query {\n        normalObjectQuery {\n          normalResolvedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query, contextValue: {} });\n\n      expect(result.data!.normalObjectQuery.normalResolvedField).toEqual(\"normalResolvedField\");\n    });\n\n    it(\"should restrict access to authed query\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        authedQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toBeDefined();\n    });\n\n    it(\"should restrict access to authed resolver\", async () => {\n      Authorized()(sampleResolver);\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n\n      // clear AuthorizedClassMetadata for other tests\n      getMetadataStorage().authorizedResolver = [];\n      const query = `query {\n        normalQuery\n      }`;\n\n      const result = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toBeDefined();\n    });\n\n    it(\"should return null when accessing nullable authed query in null mode\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n        authMode: \"null\",\n      });\n      const query = `query {\n        nullableAuthedQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.nullableAuthedQuery).toBeNull();\n      expect(result.errors).toBeUndefined();\n    });\n\n    it(\"should throw AuthenticationError when guest accessing authed query\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        authedQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n      const error = result.errors![0];\n      expect(error.originalError).toBeInstanceOf(AuthenticationError);\n      expect(error.path).toContain(\"authedQuery\");\n    });\n\n    it(\"should throw AuthorizationError when guest accessing query authed with roles\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        adminQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n      const error = result.errors![0];\n      expect(error.originalError).toBeInstanceOf(AuthorizationError);\n      expect(error.path).toContain(\"adminQuery\");\n    });\n\n    it(\"should allow for access to authed query when `authChecker` returns true\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => true,\n      });\n      const query = `query {\n        authedQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.authedQuery).toEqual(false);\n    });\n\n    it(\"should restrict access to authed object field\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          authedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n    });\n\n    it(\"should return null while accessing nullable authed object field\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          nullableAuthedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.normalObjectQuery.nullableAuthedField).toBeNull();\n    });\n\n    it(\"should throw AuthenticationError when guest accessing authed object field\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          authedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n      const error = result.errors![0];\n      expect(error.originalError).toBeInstanceOf(AuthenticationError);\n      expect(error.path).toContain(\"authedField\");\n    });\n\n    it(\"should throw AuthorizationError when guest accessing object field authed with roles\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          adminField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n      const error = result.errors![0];\n      expect(error.originalError).toBeInstanceOf(AuthorizationError);\n      expect(error.path).toContain(\"adminField\");\n    });\n\n    it(\"should allow for access to authed object field when `authChecker` returns true\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => true,\n      });\n      const query = `query {\n        normalObjectQuery {\n          authedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.normalObjectQuery.authedField).toEqual(\"authedField\");\n    });\n\n    it(\"should restrict access to authed object field from resolver\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          authedResolvedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n    });\n\n    it(\"should restrict access to inline authed object field from resolver\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => false,\n      });\n      const query = `query {\n        normalObjectQuery {\n          inlineAuthedResolvedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data).toBeNull();\n    });\n\n    it(\"should allow for access to authed object field from resolver when access granted\", async () => {\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: () => true,\n      });\n      const query = `query {\n        normalObjectQuery {\n          inlineAuthedResolvedField\n        }\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.normalObjectQuery.inlineAuthedResolvedField).toEqual(\n        \"inlineAuthedResolvedField\",\n      );\n    });\n\n    it(\"should pass roles to `authChecker` when checking for access to handler\", async () => {\n      let authCheckerRoles: string[] | undefined;\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: (_, roles) => {\n          authCheckerRoles = roles;\n          return true;\n        },\n      });\n      const query = `query {\n        adminOrRegularQuery\n      }`;\n\n      const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.adminOrRegularQuery).toEqual(false);\n      expect(authCheckerRoles).toEqual([\"ADMIN\", \"REGULAR\"]);\n    });\n\n    it(\"should pass roles from Resolver to `authChecker` when checking for access to handler\", async () => {\n      let authCheckerRoles: string[] | undefined;\n      Authorized([\"ADMIN\", \"REGULAR\"])(sampleResolver);\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: (_, roles) => {\n          authCheckerRoles = roles;\n          return true;\n        },\n      });\n\n      // clear AuthorizedClassMetadata for other tests\n      getMetadataStorage().authorizedResolver = [];\n      const query = `query {\n        normalQuery\n      }`;\n\n      const result = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.normalQuery).toEqual(true);\n      expect(authCheckerRoles).toEqual([\"ADMIN\", \"REGULAR\"]);\n    });\n\n    it(\"should pass roles from Field rather than Resolver to `authChecker`\", async () => {\n      let authCheckerRoles: string[] | undefined;\n      Authorized([\"REGULAR\"])(sampleResolver);\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: (_, roles) => {\n          authCheckerRoles = roles;\n          return true;\n        },\n      });\n\n      // clear AuthorizedClassMetadata for other tests\n      getMetadataStorage().authorizedResolver = [];\n      const query = `query {\n        adminOrRegularQuery\n      }`;\n\n      const result = await graphql({ schema: localSchema, source: query, contextValue: {} });\n\n      expect(result.data!.adminOrRegularQuery).toEqual(false);\n      expect(authCheckerRoles).toEqual([\"ADMIN\", \"REGULAR\"]);\n    });\n\n    it(\"should pass resolver data to `authChecker` when checking for access to handler\", async () => {\n      let authCheckerResolverData: any;\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: resolverData => {\n          authCheckerResolverData = resolverData;\n          return true;\n        },\n      });\n      const query = `query {\n        adminOrRegularQuery\n      }`;\n\n      const result: any = await graphql({\n        schema: localSchema,\n        source: query,\n        rootValue: { field: \"rootField\" },\n        contextValue: { field: \"contextField\" },\n      });\n\n      expect(result.data!.adminOrRegularQuery).toEqual(false);\n      expect(authCheckerResolverData.root.field).toEqual(\"rootField\");\n      expect(authCheckerResolverData.context.field).toEqual(\"contextField\");\n      expect(authCheckerResolverData.args).toEqual({});\n      expect(authCheckerResolverData.info).toBeDefined();\n    });\n  });\n\n  describe(\"with class-based auth checker\", () => {\n    it(\"should correctly call auth checker class instance 'check' method\", async () => {\n      let authCheckerResolverData: any;\n      let authCheckerRoles: any;\n      class TestAuthChecker implements AuthCheckerInterface {\n        check(resolverData: ResolverData, roles: string[]) {\n          authCheckerResolverData = resolverData;\n          authCheckerRoles = roles;\n          return false;\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [sampleResolver],\n        authChecker: TestAuthChecker,\n      });\n\n      const query = /* graphql */ `\n        query {\n          adminOrRegularQuery\n        }\n      `;\n\n      const result: any = await graphql({\n        schema: localSchema,\n        source: query,\n        rootValue: { field: \"rootField\" },\n        contextValue: { field: \"contextField\" },\n      });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toMatchInlineSnapshot(`\n        [\n          [GraphQLError: Access denied! You don't have permission for this action!],\n        ]\n      `);\n      expect(authCheckerResolverData.root).toEqual({ field: \"rootField\" });\n      expect(authCheckerResolverData.context).toEqual({ field: \"contextField\" });\n      expect(authCheckerResolverData.args).toEqual({});\n      expect(authCheckerResolverData.info).toBeDefined();\n      expect(authCheckerRoles).toEqual([\"ADMIN\", \"REGULAR\"]);\n    });\n  });\n\n  describe(\"with constant readonly array or roles\", () => {\n    let testResolver: Function;\n\n    beforeEach(() => {\n      getMetadataStorage().clear();\n\n      const CONSTANT_ROLES = [\"a\", \"b\", \"c\"] as const;\n\n      @Resolver()\n      class TestResolver {\n        @Query()\n        @Authorized(CONSTANT_ROLES)\n        authedQuery(@Ctx() ctx: any): boolean {\n          return ctx.user !== undefined;\n        }\n      }\n\n      testResolver = TestResolver;\n    });\n\n    it(\"should not throw an error\", async () => {\n      await expect(\n        buildSchema({\n          resolvers: [testResolver],\n          // dummy auth checker\n          authChecker: () => false,\n        }),\n      ).resolves.not.toThrow();\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/circular-refs.ts",
    "content": "import \"reflect-metadata\";\nimport { type IntrospectionObjectType, TypeKind, graphql } from \"graphql\";\nimport { Field, ObjectType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Circular references\", () => {\n  it(\"should resolve circular type dependencies when type functions are used\", async () => {\n    getMetadataStorage().clear();\n\n    const { CircularRef1 } = await import(\"../helpers/circular-refs/good/CircularRef1\");\n    const { CircularRef2 } = await import(\"../helpers/circular-refs/good/CircularRef2\");\n\n    @ObjectType()\n    class SampleObject {\n      @Field(() => CircularRef1)\n      ref1: any;\n\n      @Field(() => CircularRef2)\n      ref2: any;\n    }\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      objectQuery(): SampleObject {\n        return {} as any;\n      }\n    }\n\n    const {\n      schemaIntrospection: { types },\n    } = await getSchemaInfo({ resolvers: [SampleResolver] });\n    const circularRef1 = types.find(\n      type => type.name === \"CircularRef1\",\n    ) as IntrospectionObjectType;\n    const circularRef2 = types.find(\n      type => type.name === \"CircularRef2\",\n    ) as IntrospectionObjectType;\n\n    expect(circularRef1).toBeDefined();\n    expect(circularRef1.kind).toEqual(TypeKind.OBJECT);\n    expect(circularRef2).toBeDefined();\n    expect(circularRef2.kind).toEqual(TypeKind.OBJECT);\n  });\n\n  it(\"should throw error when not providing type function for circular type references\", async () => {\n    getMetadataStorage().clear();\n\n    const errorRef1 = await expectToThrow(\n      async () => (await import(\"../helpers/circular-refs/wrong/CircularRef1\")).CircularRef1,\n    );\n\n    expect(errorRef1).toBeInstanceOf(Error);\n    expect(errorRef1.message).toContain(\"provide explicit type\");\n    expect(errorRef1.message).toContain(\"ref1Field\");\n    jest.resetModules();\n\n    const errorRef2 = await expectToThrow(\n      async () => (await import(\"../helpers/circular-refs/wrong/CircularRef2\")).CircularRef2,\n    );\n    expect(errorRef2).toBeInstanceOf(Error);\n    expect(errorRef2.message).toContain(\"provide explicit type\");\n    expect(errorRef2.message).toContain(\"ref2Field\");\n    jest.resetModules();\n  });\n\n  it(\"should allow to have self-reference fields in object type\", async () => {\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      stringField!: string;\n\n      @Field(() => SampleObject, { nullable: true })\n      selfReferenceField?: SampleObject;\n\n      @Field(() => [SampleObject])\n      selfReferenceArrayField!: SampleObject[];\n    }\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      objectQuery(): SampleObject {\n        const obj: SampleObject = {\n          stringField: \"nestedStringField\",\n          selfReferenceArrayField: [],\n        };\n        obj.selfReferenceField = obj;\n        return {\n          stringField: \"stringField\",\n          selfReferenceArrayField: [obj],\n          selfReferenceField: obj,\n        };\n      }\n    }\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n    });\n    expect(schema).toBeDefined();\n\n    const query = /* graphql */ `\n      query {\n        objectQuery {\n          stringField\n          selfReferenceField {\n            stringField\n          }\n          selfReferenceArrayField {\n            selfReferenceField {\n              stringField\n            }\n          }\n        }\n      }\n    `;\n    const { data } = await graphql({ schema, source: query });\n\n    expect(data!.objectQuery).toEqual({\n      stringField: \"stringField\",\n      selfReferenceField: {\n        stringField: \"nestedStringField\",\n      },\n      selfReferenceArrayField: [\n        {\n          selfReferenceField: {\n            stringField: \"nestedStringField\",\n          },\n        },\n      ],\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/default-nullable.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type IntrospectionListTypeRef,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  TypeKind,\n} from \"graphql\";\nimport { Field, ObjectType, Query, Resolver } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"buildSchema -> nullableByDefault\", () => {\n  let SampleObjectClass: any;\n  let SampleResolverClass: any;\n\n  beforeEach(async () => {\n    getMetadataStorage().clear();\n\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      normalField!: string;\n\n      @Field(() => [String])\n      normalArrayField!: string[];\n\n      @Field({ nullable: true })\n      nullableField!: string;\n\n      @Field({ nullable: false })\n      nonNullableField!: string;\n    }\n    SampleObjectClass = SampleObject;\n\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      @Query()\n      normalQuery(): string {\n        return \"normalQuery\";\n      }\n\n      @Query(() => [String])\n      normalArrayQuery(): string[] {\n        return [\"normalArrayQuery\"];\n      }\n\n      @Query(() => String, { nullable: true })\n      nullableQuery() {\n        return null;\n      }\n\n      @Query({ nullable: false })\n      nonNullableQuery(): string {\n        return \"nonNullableQuery\";\n      }\n    }\n    SampleResolverClass = SampleResolver;\n  });\n\n  describe(\"default behavior\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n    let queryType: IntrospectionObjectType;\n    let sampleObjectType: IntrospectionObjectType;\n\n    beforeEach(async () => {\n      ({ schemaIntrospection, queryType } = await getSchemaInfo({\n        resolvers: [SampleResolverClass],\n        orphanedTypes: [SampleObjectClass],\n      }));\n      sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n    });\n\n    it(\"should emit non nullable fields by default\", async () => {\n      const normalField = sampleObjectType.fields.find(it => it.name === \"normalField\");\n      const normalFieldType = normalField!.type as IntrospectionNonNullTypeRef;\n      const normalFieldInnerType = normalFieldType.ofType as IntrospectionNamedTypeRef;\n      expect(normalFieldType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalFieldInnerType.name).toBe(\"String\");\n\n      const normalArrayField = sampleObjectType.fields.find(it => it.name === \"normalArrayField\");\n      const normalArrayFieldType = normalArrayField!.type as IntrospectionNonNullTypeRef;\n      const normalArrayFieldListType = normalArrayFieldType.ofType as IntrospectionListTypeRef;\n      const normalArrayFieldListElementType =\n        normalArrayFieldListType.ofType as IntrospectionNonNullTypeRef;\n      const normalArrayFieldListElementInnerType =\n        normalArrayFieldListElementType.ofType as IntrospectionNamedTypeRef;\n      expect(normalArrayFieldType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalArrayFieldListType.kind).toBe(TypeKind.LIST);\n      expect(normalArrayFieldListElementType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalArrayFieldListElementInnerType.kind).toBe(TypeKind.SCALAR);\n      expect(normalArrayFieldListElementInnerType.name).toBe(\"String\");\n    });\n\n    it(\"should emit non nullable queries by default\", async () => {\n      const normalQuery = queryType.fields.find(it => it.name === \"normalQuery\");\n      const normalQueryType = normalQuery!.type as IntrospectionNonNullTypeRef;\n      const normalQueryInnerType = normalQueryType.ofType as IntrospectionNamedTypeRef;\n      expect(normalQueryType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalQueryInnerType.name).toBe(\"String\");\n\n      const normalArrayQuery = queryType.fields.find(it => it.name === \"normalArrayQuery\");\n      const normalArrayQueryType = normalArrayQuery!.type as IntrospectionNonNullTypeRef;\n      const normalArrayQueryListType = normalArrayQueryType.ofType as IntrospectionListTypeRef;\n      const normalArrayQueryListElementType =\n        normalArrayQueryListType.ofType as IntrospectionNonNullTypeRef;\n      const normalArrayQueryListElementInnerType =\n        normalArrayQueryListElementType.ofType as IntrospectionNamedTypeRef;\n      expect(normalArrayQueryType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalArrayQueryListType.kind).toBe(TypeKind.LIST);\n      expect(normalArrayQueryListElementType.kind).toBe(TypeKind.NON_NULL);\n      expect(normalArrayQueryListElementInnerType.kind).toBe(TypeKind.SCALAR);\n      expect(normalArrayQueryListElementInnerType.name).toBe(\"String\");\n    });\n  });\n\n  describe(\"nullableByDefault = true\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n    let queryType: IntrospectionObjectType;\n    let sampleObjectType: IntrospectionObjectType;\n\n    beforeEach(async () => {\n      ({ schemaIntrospection, queryType } = await getSchemaInfo({\n        resolvers: [SampleResolverClass],\n        orphanedTypes: [SampleObjectClass],\n        nullableByDefault: true,\n      }));\n      sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n    });\n\n    it(\"should emit nullable fields by default\", async () => {\n      const normalField = sampleObjectType.fields.find(it => it.name === \"normalField\")!;\n      const normalFieldType = normalField.type as IntrospectionNamedTypeRef;\n      expect(normalFieldType.name).toBe(\"String\");\n\n      const normalArrayField = sampleObjectType.fields.find(it => it.name === \"normalArrayField\");\n      const normalArrayFieldType = normalArrayField!.type as IntrospectionListTypeRef;\n      const normalArrayFieldListElementInnerType =\n        normalArrayFieldType.ofType as IntrospectionNamedTypeRef;\n      expect(normalArrayFieldType.kind).toBe(TypeKind.LIST);\n      expect(normalArrayFieldListElementInnerType.kind).toBe(TypeKind.SCALAR);\n      expect(normalArrayFieldListElementInnerType.name).toBe(\"String\");\n    });\n\n    it(\"should emit nullable queries by default\", async () => {\n      const normalQuery = queryType.fields.find(it => it.name === \"normalQuery\")!;\n      const normalQueryType = normalQuery.type as IntrospectionNamedTypeRef;\n      expect(normalQueryType.name).toBe(\"String\");\n\n      const normalArrayQuery = queryType.fields.find(it => it.name === \"normalArrayQuery\");\n      const normalArrayQueryType = normalArrayQuery!.type as IntrospectionListTypeRef;\n      const normalArrayQueryListElementInnerType =\n        normalArrayQueryType.ofType as IntrospectionNamedTypeRef;\n      expect(normalArrayQueryType.kind).toBe(TypeKind.LIST);\n      expect(normalArrayQueryListElementInnerType.kind).toBe(TypeKind.SCALAR);\n      expect(normalArrayQueryListElementInnerType.name).toBe(\"String\");\n    });\n\n    it(\"shouldn't affect explicit nullability options from decorators\", async () => {\n      const nullableField = sampleObjectType.fields.find(it => it.name === \"nullableField\")!;\n      const nullableFieldType = nullableField.type as IntrospectionNamedTypeRef;\n      expect(nullableFieldType.name).toBe(\"String\");\n\n      const nonNullableField = sampleObjectType.fields.find(it => it.name === \"nonNullableField\")!;\n      const nonNullableFieldType = nonNullableField.type as IntrospectionNonNullTypeRef;\n      const nonNullableFieldInnerType = nonNullableFieldType.ofType as IntrospectionNamedTypeRef;\n      expect(nonNullableFieldType.kind).toBe(TypeKind.NON_NULL);\n      expect(nonNullableFieldInnerType.name).toBe(\"String\");\n\n      const nullableQuery = queryType.fields.find(it => it.name === \"nullableQuery\")!;\n      const nullableQueryType = nullableQuery.type as IntrospectionNamedTypeRef;\n      expect(nullableQueryType.name).toBe(\"String\");\n\n      const nonNullableQuery = queryType.fields.find(it => it.name === \"nonNullableQuery\")!;\n      const nonNullableQueryType = nonNullableQuery.type as IntrospectionNonNullTypeRef;\n      const nonNullableQueryInnerType = nonNullableQueryType.ofType as IntrospectionNamedTypeRef;\n      expect(nonNullableQueryType.kind).toBe(TypeKind.NON_NULL);\n      expect(nonNullableQueryInnerType.name).toBe(\"String\");\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/default-values.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, printType } from \"graphql\";\nimport {\n  Arg,\n  type ClassType,\n  Field,\n  InputType,\n  Query,\n  Resolver,\n  buildSchema,\n  getMetadataStorage,\n} from \"type-graphql\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"default values\", () => {\n  describe(\"dynamic default value\", () => {\n    let sampleResolver: ClassType;\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        sampleField: Date = new Date();\n      }\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n          return \"sampleQuery\";\n        }\n      }\n      sampleResolver = SampleResolver;\n\n      await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n    });\n\n    it(\"should not throw error when schema with dynamic default has been built again\", async () => {\n      await expect(buildSchema({ resolvers: [sampleResolver] })).resolves.not.toThrow();\n    });\n  });\n\n  describe(\"when disableInferringDefaultValues is set\", () => {\n    let schema: GraphQLSchema;\n\n    beforeEach(async () => {\n      getMetadataStorage().clear();\n      @InputType()\n      class SampleInitializerInput {\n        @Field()\n        inputField: string = \"defaultValueFromPropertyInitializer\";\n      }\n\n      @InputType()\n      class SampleOptionInput {\n        @Field({ defaultValue: \"defaultValueFromOption\" })\n        inputField!: string;\n      }\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(\n          @Arg(\"input1\") _input1: SampleInitializerInput,\n          @Arg(\"input2\") _input2: SampleOptionInput,\n        ): string {\n          return \"sampleQuery\";\n        }\n      }\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        disableInferringDefaultValues: true,\n      });\n    });\n\n    it(\"should not infer default value from a property initializer\", async () => {\n      const sampleInitializerInputType = schema.getType(\"SampleInitializerInput\")!;\n      const sampleInitializerInputSDL = printType(sampleInitializerInputType);\n\n      expect(sampleInitializerInputSDL).toMatchInlineSnapshot(`\n        \"input SampleInitializerInput {\n          inputField: String!\n        }\"\n      `);\n    });\n\n    it(\"should read default value from a decorator option\", async () => {\n      const sampleOptionInputType = schema.getType(\"SampleOptionInput\")!;\n      const sampleOptionInputSDL = printType(sampleOptionInputType);\n\n      expect(sampleOptionInputSDL).toMatchInlineSnapshot(`\n        \"input SampleOptionInput {\n          inputField: String! = \"defaultValueFromOption\"\n        }\"\n      `);\n    });\n  });\n\n  describe(\"with nullable settings\", () => {\n    describe(\"when `nullable: false` and defaultValue is provided\", () => {\n      let schema: GraphQLSchema;\n\n      beforeEach(async () => {\n        getMetadataStorage().clear();\n        @InputType()\n        class SampleInput {\n          @Field({ defaultValue: \"stringDefaultValue\", nullable: false })\n          inputField!: string;\n        }\n\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n            return \"sampleQuery\";\n          }\n        }\n        schema = await buildSchema({ resolvers: [SampleResolver] });\n      });\n\n      it(\"should emit field of type non-nullable string with default value\", async () => {\n        const sampleInputType = schema.getType(\"SampleInput\")!;\n        const sampleInputSDL = printType(sampleInputType);\n\n        expect(sampleInputSDL).toMatchInlineSnapshot(`\n          \"input SampleInput {\n            inputField: String! = \"stringDefaultValue\"\n          }\"\n        `);\n      });\n    });\n\n    describe(\"when `nullable: true` and defaultValue is provided\", () => {\n      let schema: GraphQLSchema;\n\n      beforeEach(async () => {\n        getMetadataStorage().clear();\n        @InputType()\n        class SampleInput {\n          @Field({ defaultValue: \"stringDefaultValue\", nullable: true })\n          inputField!: string;\n        }\n\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n            return \"sampleQuery\";\n          }\n        }\n        schema = await buildSchema({ resolvers: [SampleResolver] });\n      });\n\n      it(\"should emit field of type nullable string with default value\", async () => {\n        const sampleInputType = schema.getType(\"SampleInput\")!;\n        const sampleInputSDL = printType(sampleInputType);\n\n        expect(sampleInputSDL).toMatchInlineSnapshot(`\n          \"input SampleInput {\n            inputField: String = \"stringDefaultValue\"\n          }\"\n        `);\n      });\n    });\n\n    describe(\"when `nullableByDefault: true`\", () => {\n      describe(\"when defaultValue is provided\", () => {\n        let schema: GraphQLSchema;\n\n        beforeEach(async () => {\n          getMetadataStorage().clear();\n          @InputType()\n          class SampleInput {\n            @Field({ defaultValue: \"stringDefaultValue\" })\n            inputField!: string;\n          }\n\n          @Resolver()\n          class SampleResolver {\n            @Query()\n            sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n              return \"sampleQuery\";\n            }\n          }\n          schema = await buildSchema({\n            resolvers: [SampleResolver],\n            nullableByDefault: true,\n          });\n        });\n\n        it(\"should emit field of type nullable string with default value\", async () => {\n          const sampleInputType = schema.getType(\"SampleInput\")!;\n          const sampleInputSDL = printType(sampleInputType);\n\n          expect(sampleInputSDL).toMatchInlineSnapshot(`\n            \"input SampleInput {\n              inputField: String = \"stringDefaultValue\"\n            }\"\n          `);\n        });\n      });\n\n      describe(\"when `nullable: false` and defaultValue is provided\", () => {\n        let schema: GraphQLSchema;\n\n        beforeEach(async () => {\n          getMetadataStorage().clear();\n          @InputType()\n          class SampleInput {\n            @Field({ defaultValue: \"stringDefaultValue\", nullable: false })\n            inputField!: string;\n          }\n\n          @Resolver()\n          class SampleResolver {\n            @Query()\n            sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n              return \"sampleQuery\";\n            }\n          }\n          schema = await buildSchema({\n            resolvers: [SampleResolver],\n            nullableByDefault: true,\n          });\n        });\n\n        it(\"should emit field of type non-nullable string with default value\", async () => {\n          const sampleInputType = schema.getType(\"SampleInput\")!;\n          const sampleInputSDL = printType(sampleInputType);\n\n          expect(sampleInputSDL).toMatchInlineSnapshot(`\n            \"input SampleInput {\n              inputField: String! = \"stringDefaultValue\"\n            }\"\n          `);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/deprecation.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  printType,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  Field,\n  InputType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n} from \"type-graphql\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Deprecation\", () => {\n  describe(\"Schema\", () => {\n    let schema: GraphQLSchema;\n    let schemaIntrospection: IntrospectionSchema;\n    let mutationType: IntrospectionObjectType;\n    let queryType: IntrospectionObjectType;\n\n    beforeAll(async () => {\n      // Create sample definitions\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        normalField!: string;\n\n        @Field({ deprecationReason: \"sample object field deprecation reason\" })\n        deprecatedField!: string;\n\n        @Field({ deprecationReason: \"sample object getter field deprecation reason\" })\n        // eslint-disable-next-line @typescript-eslint/class-literal-property-style\n        get deprecatedGetterField(): string {\n          return \"deprecatedGetterField\";\n        }\n\n        @Field({ deprecationReason: \"sample object method field deprecation reason\" })\n        methodField(): string {\n          return \"methodField\";\n        }\n      }\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        normalField!: string;\n\n        @Field({\n          deprecationReason: \"sample input field deprecation reason\",\n          nullable: true,\n        })\n        deprecatedField!: string;\n      }\n\n      @ArgsType()\n      class SampleArgs {\n        @Field()\n        normalArg!: string;\n\n        @Field({\n          deprecationReason: \"sample args field deprecation reason\",\n          nullable: true,\n        })\n        deprecatedArg!: string;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        normalQuery(): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query()\n        inputQuery(@Arg(\"input\") _input: SampleInput): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query()\n        argsQuery(@Args() _args: SampleArgs): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query()\n        deprecatedArgQuery(\n          @Arg(\"arg\", {\n            deprecationReason: \"sample query arg deprecation reason\",\n            nullable: true,\n          })\n          _arg?: string,\n        ): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query({ deprecationReason: \"sample query deprecation reason\" })\n        describedQuery(): string {\n          return \"describedQuery\";\n        }\n\n        @Mutation()\n        normalMutation(): string {\n          return \"normalMutation\";\n        }\n\n        @Mutation({ deprecationReason: \"sample mutation deprecation reason\" })\n        describedMutation(): string {\n          return \"describedMutation\";\n        }\n      }\n\n      // get builded schema info from retrospection\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n      schema = schemaInfo.schema;\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      queryType = schemaInfo.queryType;\n      mutationType = schemaInfo.mutationType!;\n    });\n\n    it(\"should generate proper object fields deprecation reason\", async () => {\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n      const normalField = sampleObjectType.fields.find(field => field.name === \"normalField\")!;\n      const deprecatedField = sampleObjectType.fields.find(\n        field => field.name === \"deprecatedField\",\n      )!;\n      const deprecatedGetterField = sampleObjectType.fields.find(\n        field => field.name === \"deprecatedGetterField\",\n      )!;\n      const methodField = sampleObjectType.fields.find(field => field.name === \"methodField\")!;\n\n      expect(normalField.isDeprecated).toBeFalsy();\n      expect(normalField.deprecationReason).toBeNull();\n      expect(deprecatedField.isDeprecated).toBeTruthy();\n      expect(deprecatedField.deprecationReason).toEqual(\"sample object field deprecation reason\");\n      expect(deprecatedGetterField.isDeprecated).toBeTruthy();\n      expect(deprecatedGetterField.deprecationReason).toEqual(\n        \"sample object getter field deprecation reason\",\n      );\n      expect(methodField.isDeprecated).toBeTruthy();\n      expect(methodField.deprecationReason).toEqual(\n        \"sample object method field deprecation reason\",\n      );\n    });\n\n    it(\"should generate proper input type fields deprecation reason\", async () => {\n      const sampleInputType = schema.getType(\"SampleInput\")!;\n      const sampleInputTypeSDL = printType(sampleInputType);\n\n      expect(sampleInputTypeSDL).toMatchInlineSnapshot(`\n        \"input SampleInput {\n          normalField: String!\n          deprecatedField: String @deprecated(reason: \"sample input field deprecation reason\")\n        }\"\n      `);\n    });\n\n    it(\"should generate proper query type deprecation reason\", async () => {\n      const normalQuery = queryType.fields.find(field => field.name === \"normalQuery\")!;\n      const describedQuery = queryType.fields.find(field => field.name === \"describedQuery\")!;\n\n      expect(normalQuery.isDeprecated).toBeFalsy();\n      expect(normalQuery.deprecationReason).toBeNull();\n      expect(describedQuery.isDeprecated).toBeTruthy();\n      expect(describedQuery.deprecationReason).toEqual(\"sample query deprecation reason\");\n    });\n\n    it(\"should generate proper mutation type deprecation reason\", async () => {\n      const normalMutation = mutationType.fields.find(field => field.name === \"normalMutation\")!;\n      const describedMutation = mutationType.fields.find(\n        field => field.name === \"describedMutation\",\n      )!;\n\n      expect(normalMutation.isDeprecated).toBeFalsy();\n      expect(normalMutation.deprecationReason).toBeNull();\n      expect(describedMutation.isDeprecated).toBeTruthy();\n      expect(describedMutation.deprecationReason).toEqual(\"sample mutation deprecation reason\");\n    });\n\n    it(\"should generate proper single arg deprecation reason\", async () => {\n      const queryObjectType = schema.getQueryType()!;\n      const queryObjectTypeSDL = printType(queryObjectType);\n\n      expect(queryObjectTypeSDL).toContain(\n        'deprecatedArgQuery(arg: String @deprecated(reason: \"sample query arg deprecation reason\"))',\n      );\n    });\n\n    it(\"should generate proper args type fields deprecation reason\", async () => {\n      const queryObjectType = schema.getQueryType()!;\n      const queryObjectTypeSDL = printType(queryObjectType);\n\n      expect(queryObjectTypeSDL).toContain(\n        'argsQuery(normalArg: String!, deprecatedArg: String @deprecated(reason: \"sample args field deprecation reason\")): SampleObject!',\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/description.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type IntrospectionInputObjectType,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  Field,\n  InputType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n} from \"type-graphql\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Description\", () => {\n  describe(\"Schema\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n    let mutationType: IntrospectionObjectType;\n    let queryType: IntrospectionObjectType;\n\n    beforeAll(async () => {\n      // Create sample definitions\n\n      @ObjectType({ description: \"sample object description\" })\n      class SampleObject {\n        @Field()\n        normalField!: string;\n\n        @Field({ description: \"sample object field description\" })\n        describedField!: string;\n\n        @Field({ description: \"sample object getter field description\" })\n        // eslint-disable-next-line @typescript-eslint/class-literal-property-style\n        get describedGetterField(): string {\n          return \"describedGetterField\";\n        }\n\n        @Field({ description: \"sample object method field description\" })\n        methodField(\n          @Arg(\"arg\", { description: \"sample object method arg description\" }) _arg: string,\n        ): string {\n          return \"methodField\";\n        }\n      }\n\n      @InputType({ description: \"sample input description\" })\n      class SampleInput {\n        @Field()\n        normalField!: string;\n\n        @Field({ description: \"sample input field description\" })\n        describedField!: string;\n      }\n\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        normalField!: string;\n\n        @Field({ description: \"sample argument field description\" })\n        describedField!: string;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        normalQuery(): string {\n          return \"normalQuery\";\n        }\n\n        @Query({ description: \"sample query description\" })\n        describedQuery(\n          @Arg(\"normalArg\") _normalArg: string,\n          @Arg(\"describedArg\", { description: \"sample query arg description\" })\n          _describedArg: string,\n        ): string {\n          return \"describedQuery\";\n        }\n\n        @Query()\n        argumentedQuery(@Args() _args: SampleArguments): string {\n          return \"argumentedQuery\";\n        }\n\n        @Query()\n        inputQuery(@Arg(\"input\") _input: SampleInput): string {\n          return \"inputQuery\";\n        }\n\n        @Mutation()\n        normalMutation(): string {\n          return \"normalMutation\";\n        }\n\n        @Mutation({ description: \"sample mutation description\" })\n        describedMutation(\n          @Arg(\"normalArg\") _normalArg: string,\n          @Arg(\"describedArg\", { description: \"sample mutation arg description\" })\n          _describedArg: string,\n        ): string {\n          return \"describedMutation\";\n        }\n\n        @Mutation()\n        argumentedMutation(@Args() _args: SampleArguments): string {\n          return \"argumentedMutation\";\n        }\n\n        @Mutation()\n        inputMutation(@Arg(\"input\") _input: SampleInput): string {\n          return \"inputMutation\";\n        }\n      }\n\n      // Get builded schema info from retrospection\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        orphanedTypes: [SampleObject],\n      });\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      queryType = schemaInfo.queryType;\n      mutationType = schemaInfo.mutationType!;\n    });\n\n    it(\"should generate proper object type description\", async () => {\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n\n      expect(sampleObjectType.description).toEqual(\"sample object description\");\n    });\n\n    it(\"should generate proper object fields descriptions\", async () => {\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n      const normalField = sampleObjectType.fields.find(field => field.name === \"normalField\")!;\n      const describedField = sampleObjectType.fields.find(\n        field => field.name === \"describedField\",\n      )!;\n      const describedGetterField = sampleObjectType.fields.find(\n        field => field.name === \"describedGetterField\",\n      )!;\n      const methodField = sampleObjectType.fields.find(field => field.name === \"methodField\")!;\n\n      expect(normalField.description).toBeNull();\n      expect(describedField.description).toEqual(\"sample object field description\");\n      expect(describedGetterField.description).toEqual(\"sample object getter field description\");\n      expect(methodField.description).toEqual(\"sample object method field description\");\n    });\n\n    it(\"should generate proper query type description\", async () => {\n      const normalQuery = queryType.fields.find(field => field.name === \"normalQuery\")!;\n      const describedQuery = queryType.fields.find(field => field.name === \"describedQuery\")!;\n\n      expect(normalQuery.description).toBeNull();\n      expect(describedQuery.description).toEqual(\"sample query description\");\n    });\n\n    it(\"should generate proper query inline args description\", async () => {\n      const describedQuery = queryType.fields.find(field => field.name === \"describedQuery\")!;\n      const normalArg = describedQuery.args.find(arg => arg.name === \"normalArg\")!;\n      const describedArg = describedQuery.args.find(arg => arg.name === \"describedArg\")!;\n\n      expect(describedQuery.args).toHaveLength(2);\n      expect(normalArg.description).toBeNull();\n      expect(describedArg.description).toEqual(\"sample query arg description\");\n    });\n\n    it(\"should generate proper query object args description\", async () => {\n      const argumentedQuery = queryType.fields.find(field => field.name === \"argumentedQuery\")!;\n      const normalField = argumentedQuery.args.find(arg => arg.name === \"normalField\")!;\n      const describedField = argumentedQuery.args.find(arg => arg.name === \"describedField\")!;\n\n      expect(argumentedQuery.args).toHaveLength(2);\n      expect(normalField.description).toBeNull();\n      expect(describedField.description).toEqual(\"sample argument field description\");\n    });\n\n    it(\"should generate proper mutation type description\", async () => {\n      const normalMutation = mutationType.fields.find(field => field.name === \"normalMutation\")!;\n      const describedMutation = mutationType.fields.find(\n        field => field.name === \"describedMutation\",\n      )!;\n\n      expect(normalMutation.description).toBeNull();\n      expect(describedMutation.description).toEqual(\"sample mutation description\");\n    });\n\n    it(\"should generate proper mutation inline args description\", async () => {\n      const describedQuery = mutationType.fields.find(field => field.name === \"describedMutation\")!;\n      const normalArg = describedQuery.args.find(arg => arg.name === \"normalArg\")!;\n      const describedArg = describedQuery.args.find(arg => arg.name === \"describedArg\")!;\n\n      expect(describedQuery.args).toHaveLength(2);\n      expect(normalArg.description).toBeNull();\n      expect(describedArg.description).toEqual(\"sample mutation arg description\");\n    });\n\n    it(\"should generate proper mutation object args description\", async () => {\n      const argumentedMutation = mutationType.fields.find(\n        field => field.name === \"argumentedMutation\",\n      )!;\n      const normalField = argumentedMutation.args.find(arg => arg.name === \"normalField\")!;\n      const describedField = argumentedMutation.args.find(arg => arg.name === \"describedField\")!;\n\n      expect(argumentedMutation.args).toHaveLength(2);\n      expect(normalField.description).toBeNull();\n      expect(describedField.description).toEqual(\"sample argument field description\");\n    });\n\n    it(\"should generate proper input type description\", async () => {\n      const sampleInputType = schemaIntrospection.types.find(\n        type => type.name === \"SampleInput\",\n      ) as IntrospectionInputObjectType;\n\n      expect(sampleInputType.description).toEqual(\"sample input description\");\n    });\n\n    it(\"should generate proper input fields description\", async () => {\n      const sampleInputType = schemaIntrospection.types.find(\n        type => type.name === \"SampleInput\",\n      ) as IntrospectionInputObjectType;\n      const normalField = sampleInputType.inputFields.find(field => field.name === \"normalField\")!;\n      const describedField = sampleInputType.inputFields.find(\n        field => field.name === \"describedField\",\n      )!;\n\n      expect(normalField.description).toBeNull();\n      expect(describedField.description).toEqual(\"sample input field description\");\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/directives.ts",
    "content": "import \"reflect-metadata\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport {\n  type GraphQLInputObjectType,\n  type GraphQLInterfaceType,\n  type GraphQLObjectType,\n  type GraphQLSchema,\n  OperationTypeNode,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  Directive,\n  Field,\n  InputType,\n  InterfaceType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  Subscription,\n  buildSchema,\n} from \"type-graphql\";\nimport { InvalidDirectiveError } from \"@/errors/InvalidDirectiveError\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { assertValidDirective } from \"../helpers/directives/assertValidDirective\";\nimport { testDirective, testDirectiveTransformer } from \"../helpers/directives/TestDirective\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\n\ndescribe(\"Directives\", () => {\n  describe(\"Schema\", () => {\n    beforeEach(async () => {\n      getMetadataStorage().clear();\n    });\n\n    describe(\"on ObjectType\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Directive(\"@test\")\n        @ObjectType()\n        class SampleObject {\n          @Field()\n          sampleField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleObject {\n            return { sampleField: \"sampleField\" };\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleObjectTypeInfo = schema.getType(\"SampleObject\") as GraphQLObjectType;\n\n        expect(() => {\n          assertValidDirective(sampleObjectTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleObjectTypeInfo = schema.getType(\"SampleObject\") as GraphQLObjectType;\n\n        expect(sampleObjectTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on ObjectType field\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @ObjectType()\n        class SampleObject {\n          @Field()\n          @Directive(\"@test\")\n          sampleField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleObject {\n            return { sampleField: \"sampleField\" };\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleObject\") as GraphQLObjectType\n        ).getFields().sampleField;\n\n        expect(() => {\n          assertValidDirective(sampleFieldTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleObject\") as GraphQLObjectType\n        ).getFields().sampleField;\n\n        expect(sampleFieldTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on ObjectType field argument\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @ArgsType()\n        class SampleArgs {\n          @Directive(\"@test\")\n          @Field()\n          sampleArgument!: string;\n        }\n        @ObjectType()\n        class SampleObject {\n          @Field()\n          sampleField(@Args() { sampleArgument }: SampleArgs): string {\n            return sampleArgument;\n          }\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleObject {\n            return new SampleObject();\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleFieldArgTypeInfo = (\n          schema.getType(\"SampleObject\") as GraphQLObjectType\n        ).getFields().sampleField.args[0];\n\n        expect(() => {\n          assertValidDirective(sampleFieldArgTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleFieldArgTypeInfo = (\n          schema.getType(\"SampleObject\") as GraphQLObjectType\n        ).getFields().sampleField.args[0];\n\n        expect(sampleFieldArgTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on InterfaceType\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Directive(\"@test\")\n        @InterfaceType()\n        class SampleInterface {\n          @Field()\n          sampleField!: string;\n        }\n        @ObjectType({ implements: [SampleInterface] })\n        class SampleObject extends SampleInterface {}\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleInterface {\n            const sampleObject = new SampleObject();\n            sampleObject.sampleField = \"sampleField\";\n            return sampleObject;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          orphanedTypes: [SampleObject],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleInterfaceTypeInfo = schema.getType(\"SampleInterface\") as GraphQLInterfaceType;\n\n        expect(() => {\n          assertValidDirective(sampleInterfaceTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleInterfaceTypeInfo = schema.getType(\"SampleInterface\") as GraphQLInterfaceType;\n\n        expect(sampleInterfaceTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on InterfaceType field\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @InterfaceType()\n        class SampleInterface {\n          @Directive(\"@test\")\n          @Field()\n          sampleField!: string;\n        }\n        @ObjectType({ implements: [SampleInterface] })\n        class SampleObject extends SampleInterface {}\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleInterface {\n            const sampleObject = new SampleObject();\n            sampleObject.sampleField = \"sampleField\";\n            return sampleObject;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          orphanedTypes: [SampleObject],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleInterface\") as GraphQLInterfaceType\n        ).getFields().sampleField;\n\n        expect(() => {\n          assertValidDirective(sampleFieldTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleInterface\") as GraphQLInterfaceType\n        ).getFields().sampleField;\n\n        expect(sampleFieldTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on InputType\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Directive(\"@test\")\n        @InputType()\n        class SampleInput {\n          @Field()\n          sampleField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(@Arg(\"input\") _input: SampleInput): boolean {\n            return true;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleInputTypeInfo = schema.getType(\"SampleInput\") as GraphQLInputObjectType;\n\n        expect(() => {\n          assertValidDirective(sampleInputTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleInputTypeInfo = schema.getType(\"SampleInput\") as GraphQLInputObjectType;\n\n        expect(sampleInputTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on InputType field\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @InputType()\n        class SampleInput {\n          @Field()\n          @Directive(\"@test\")\n          sampleField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(@Arg(\"input\") _input: SampleInput): boolean {\n            return true;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleInput\") as GraphQLInputObjectType\n        ).getFields().sampleField;\n\n        expect(() => {\n          assertValidDirective(sampleFieldTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleFieldTypeInfo = (\n          schema.getType(\"SampleInput\") as GraphQLInputObjectType\n        ).getFields().sampleField;\n\n        expect(sampleFieldTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on Query\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Resolver()\n        class SampleResolver {\n          @Directive(\"@test\")\n          @Query()\n          sampleQuery(): boolean {\n            return true;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleQueryInfo = schema\n          .getRootType(OperationTypeNode.QUERY)!\n          .getFields().sampleQuery;\n\n        expect(() => {\n          assertValidDirective(sampleQueryInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleQueryInfo = schema\n          .getRootType(OperationTypeNode.QUERY)!\n          .getFields().sampleQuery;\n\n        expect(sampleQueryInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on Query field argument using @Args\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @ArgsType()\n        class SampleArgs {\n          @Directive(\"@test\")\n          @Field()\n          sampleArgument!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(@Args() { sampleArgument }: SampleArgs): string {\n            return sampleArgument;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleQueryArgTypeInfo = (schema.getType(\"Query\") as GraphQLObjectType).getFields()\n          .sampleQuery.args[0];\n\n        expect(() => {\n          assertValidDirective(sampleQueryArgTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleQueryArgTypeInfo = (schema.getType(\"Query\") as GraphQLObjectType).getFields()\n          .sampleQuery.args[0];\n\n        expect(sampleQueryArgTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on Query field argument using @Arg\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(\n            @Arg(\"sampleArgument\")\n            @Directive(\"@test\")\n            sampleArgument: string,\n          ): string {\n            return sampleArgument;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleQueryArgTypeInfo = (schema.getType(\"Query\") as GraphQLObjectType).getFields()\n          .sampleQuery.args[0];\n\n        expect(() => {\n          assertValidDirective(sampleQueryArgTypeInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleQueryArgTypeInfo = (schema.getType(\"Query\") as GraphQLObjectType).getFields()\n          .sampleQuery.args[0];\n\n        expect(sampleQueryArgTypeInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on Mutation\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): boolean {\n            return true;\n          }\n\n          @Directive(\"@test\")\n          @Mutation()\n          sampleMutation(): boolean {\n            return true;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleMutationInfo = schema\n          .getRootType(OperationTypeNode.MUTATION)!\n          .getFields().sampleMutation;\n\n        expect(() => {\n          assertValidDirective(sampleMutationInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleMutationInfo = schema\n          .getRootType(OperationTypeNode.MUTATION)!\n          .getFields().sampleMutation;\n\n        expect(sampleMutationInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n\n    describe(\"on Subscription\", () => {\n      let schema: GraphQLSchema;\n      beforeAll(async () => {\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): boolean {\n            return true;\n          }\n\n          @Directive(\"@test\")\n          @Subscription({ topics: \"sample\" })\n          sampleSubscription(): boolean {\n            return true;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          directives: [testDirective],\n          validate: false,\n          pubSub: createPubSub(),\n        });\n        schema = testDirectiveTransformer(schema);\n      });\n\n      it(\"should properly emit directive in AST\", () => {\n        const sampleSubscriptionInfo = schema\n          .getRootType(OperationTypeNode.SUBSCRIPTION)!\n          .getFields().sampleSubscription;\n\n        expect(() => {\n          assertValidDirective(sampleSubscriptionInfo.astNode, \"test\");\n        }).not.toThrow();\n      });\n\n      it(\"should properly apply directive mapper\", async () => {\n        const sampleSubscriptionInfo = schema\n          .getRootType(OperationTypeNode.SUBSCRIPTION)!\n          .getFields().sampleSubscription;\n\n        expect(sampleSubscriptionInfo.extensions).toMatchObject({\n          TypeGraphQL: { isMappedByDirective: true },\n        });\n      });\n    });\n  });\n\n  describe(\"multiline and leading white spaces\", () => {\n    let schema: GraphQLSchema;\n    beforeAll(async () => {\n      @Resolver()\n      class SampleResolver {\n        @Directive(\"\\n@test\")\n        @Query()\n        multiline(): boolean {\n          return true;\n        }\n\n        @Directive(\" @test\")\n        @Query()\n        leadingWhiteSpaces(): boolean {\n          return true;\n        }\n\n        @Directive(\"\\n @test\")\n        @Query()\n        multilineAndLeadingWhiteSpaces(): boolean {\n          return true;\n        }\n\n        @Directive(`\n          @test(\n            argNonNullDefault: \"argNonNullDefault\",\n            argNullDefault: \"argNullDefault\",\n            argNull: \"argNull\"\n          )\n        `)\n        @Query()\n        rawMultilineAndLeadingWhiteSpaces(): boolean {\n          return true;\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        directives: [testDirective],\n        validate: false,\n      });\n      schema = testDirectiveTransformer(schema);\n    });\n\n    it(\"should properly emit directive in AST\", () => {\n      const multilineInfo = schema.getRootType(OperationTypeNode.QUERY)!.getFields().multiline;\n      const leadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().leadingWhiteSpaces;\n      const multilineAndLeadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().multilineAndLeadingWhiteSpaces;\n      const rawMultilineAndLeadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().rawMultilineAndLeadingWhiteSpaces;\n\n      expect(() => {\n        assertValidDirective(multilineInfo.astNode, \"test\");\n        assertValidDirective(leadingWhiteSpacesInfo.astNode, \"test\");\n        assertValidDirective(multilineAndLeadingWhiteSpacesInfo.astNode, \"test\");\n        assertValidDirective(rawMultilineAndLeadingWhiteSpacesInfo.astNode, \"test\", {\n          argNonNullDefault: `\"argNonNullDefault\"`,\n          argNullDefault: `\"argNullDefault\"`,\n          argNull: `\"argNull\"`,\n        });\n      }).not.toThrow();\n    });\n\n    it(\"should properly apply directive mapper\", async () => {\n      const multilineInfo = schema.getRootType(OperationTypeNode.QUERY)!.getFields().multiline;\n      const leadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().leadingWhiteSpaces;\n      const multilineAndLeadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().multilineAndLeadingWhiteSpaces;\n      const rawMultilineAndLeadingWhiteSpacesInfo = schema\n        .getRootType(OperationTypeNode.QUERY)!\n        .getFields().rawMultilineAndLeadingWhiteSpaces;\n\n      expect(multilineInfo.extensions).toMatchObject({\n        TypeGraphQL: { isMappedByDirective: true },\n      });\n      expect(leadingWhiteSpacesInfo.extensions).toMatchObject({\n        TypeGraphQL: { isMappedByDirective: true },\n      });\n      expect(multilineAndLeadingWhiteSpacesInfo.extensions).toMatchObject({\n        TypeGraphQL: { isMappedByDirective: true },\n      });\n      expect(rawMultilineAndLeadingWhiteSpacesInfo.extensions).toMatchObject({\n        TypeGraphQL: { isMappedByDirective: true },\n      });\n    });\n  });\n\n  describe(\"errors\", () => {\n    beforeEach(async () => {\n      getMetadataStorage().clear();\n    });\n\n    it(\"throws error on multiple directive definitions\", async () => {\n      @Resolver()\n      class InvalidQuery {\n        @Query()\n        @Directive(\"@upper @append\")\n        invalid(): string {\n          return \"invalid\";\n        }\n      }\n\n      const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] }));\n\n      expect(error).toBeInstanceOf(InvalidDirectiveError);\n      expect(error.message).toContain(\n        'Please pass only one directive name or definition at a time to the @Directive decorator \"@upper @append\"',\n      );\n    });\n\n    it(\"throws error when parsing invalid directives\", async () => {\n      @Resolver()\n      class InvalidQuery {\n        @Query()\n        @Directive(\"@invalid(@directive)\")\n        invalid(): string {\n          return \"invalid\";\n        }\n      }\n\n      const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] }));\n\n      expect(error).toBeInstanceOf(InvalidDirectiveError);\n      expect(error.message).toContain('Error parsing directive definition \"@invalid(@directive)\"');\n    });\n\n    it(\"throws error when no directives are defined\", async () => {\n      @Resolver()\n      class InvalidQuery {\n        @Query()\n        @Directive(\"\")\n        invalid(): string {\n          return \"invalid\";\n        }\n      }\n\n      const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] }));\n\n      expect(error).toBeInstanceOf(InvalidDirectiveError);\n      expect(error.message).toContain(\n        \"Please pass at-least one directive name or definition to the @Directive decorator\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/emit-schema-sdl.ts",
    "content": "import \"reflect-metadata\";\nimport fs from \"node:fs\";\nimport asyncFs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { type GraphQLSchema } from \"graphql\";\nimport shelljs from \"shelljs\";\nimport {\n  Field,\n  ObjectType,\n  type PrintSchemaOptions,\n  Query,\n  Resolver,\n  buildSchema,\n  buildSchemaSync,\n  defaultPrintSchemaOptions,\n  emitSchemaDefinitionFile,\n  emitSchemaDefinitionFileSync,\n} from \"type-graphql\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\n\nconst TEST_DIR = path.resolve(process.cwd(), \"tests\", \"test-output-dir\");\n\ndescribe(\"Emitting schema definition file\", () => {\n  let schema: GraphQLSchema;\n  let MyResolverClass: any;\n\n  beforeAll(async () => {\n    @ObjectType()\n    class MyObject {\n      @Field()\n      normalProperty!: string;\n\n      @Field({ description: \"Description test\" })\n      descriptionProperty!: boolean;\n    }\n\n    @Resolver()\n    class MyResolver {\n      @Query()\n      myQuery(): MyObject {\n        return {} as MyObject;\n      }\n    }\n\n    MyResolverClass = MyResolver;\n\n    schema = await buildSchema({\n      resolvers: [MyResolver],\n    });\n  });\n\n  afterEach(() => {\n    jest.restoreAllMocks();\n    shelljs.rm(\"-rf\", TEST_DIR);\n  });\n\n  function checkSchemaSDL(\n    SDL: string,\n    { sortedSchema }: PrintSchemaOptions = defaultPrintSchemaOptions,\n  ) {\n    expect(SDL).toContain(\"THIS FILE WAS GENERATED\");\n    expect(SDL).toContain(\"MyObject\");\n    if (sortedSchema) {\n      expect(SDL.indexOf(\"descriptionProperty\")).toBeLessThan(SDL.indexOf(\"normalProperty\"));\n    } else {\n      expect(SDL.indexOf(\"descriptionProperty\")).toBeGreaterThan(SDL.indexOf(\"normalProperty\"));\n    }\n    expect(SDL).toContain(`\"\"\"Description test\"\"\"`);\n  }\n\n  describe(\"emitSchemaDefinitionFile\", () => {\n    it(\"should write file with schema SDL successfully\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test1\", \"schema.graphql\");\n      await emitSchemaDefinitionFile(targetPath, schema);\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should use provided options to write file with schema SDL\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test1\", \"schema.graphql\");\n      const options: PrintSchemaOptions = {\n        sortedSchema: false,\n      };\n      await emitSchemaDefinitionFile(targetPath, schema, options);\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), options);\n    });\n\n    it(\"should throw error when unknown error occur while writing file with schema SDL\", async () => {\n      jest.spyOn(asyncFs, \"writeFile\").mockRejectedValueOnce({ code: \"TEST ERROR\" });\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"fail1\", \"schema.graphql\");\n      let error;\n      try {\n        await emitSchemaDefinitionFile(targetPath, schema);\n      } catch (e) {\n        error = e;\n      }\n      expect(error).toEqual({ code: \"TEST ERROR\" });\n      expect(fs.existsSync(targetPath)).toEqual(false);\n    });\n\n    it(\"should throw error when unknown error occur while creating directory with schema SDL\", async () => {\n      jest.spyOn(asyncFs, \"mkdir\").mockRejectedValueOnce({ code: \"TEST ERROR\" });\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"fail2\", \"schema.graphql\");\n      let error;\n      try {\n        await emitSchemaDefinitionFile(targetPath, schema);\n      } catch (e) {\n        error = e;\n      }\n      expect(error).toEqual({ code: \"TEST ERROR\" });\n      expect(fs.existsSync(targetPath)).toEqual(false);\n    });\n  });\n\n  describe(\"emitSchemaDefinitionFileSync\", () => {\n    it(\"should write file with schema SDL successfully\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test2\", \"schema.graphql\");\n      emitSchemaDefinitionFileSync(targetPath, schema);\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should use provided options to write file with schema SDL\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test1\", \"schema.graphql\");\n      const options: PrintSchemaOptions = {\n        sortedSchema: false,\n      };\n      emitSchemaDefinitionFileSync(targetPath, schema, options);\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), options);\n    });\n\n    it(\"should throw error when unknown error occur while writing file with schema SDL\", async () => {\n      jest.spyOn(fs, \"writeFileSync\").mockImplementationOnce(() => {\n        throw new Error(\"TYPE_GRAPHQL_WRITE_FILE_SYNC_ERROR\");\n      });\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"fail3\", \"schema.graphql\");\n      const error = await expectToThrow(() => emitSchemaDefinitionFileSync(targetPath, schema));\n\n      expect(error.message).toStrictEqual(\"TYPE_GRAPHQL_WRITE_FILE_SYNC_ERROR\");\n      expect(fs.existsSync(targetPath)).toEqual(false);\n    });\n\n    it(\"should throw error when unknown error occur while creating directory with schema SDL\", async () => {\n      jest.spyOn(fs, \"mkdirSync\").mockImplementationOnce(() => {\n        throw new Error(\"TYPE_GRAPHQL_MKDIR_SYNC_ERROR\");\n      });\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"fail4\", \"schema.graphql\");\n      const error = await expectToThrow(() => emitSchemaDefinitionFileSync(targetPath, schema));\n\n      expect(error.message).toStrictEqual(\"TYPE_GRAPHQL_MKDIR_SYNC_ERROR\");\n      expect(fs.existsSync(targetPath)).toEqual(false);\n    });\n  });\n\n  describe(\"buildSchema\", () => {\n    it(\"should generate schema SDL file on selected file path\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test3\", \"schema.graphql\");\n      await buildSchema({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: targetPath,\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should generate schema SDL file in current working dir\", async () => {\n      jest.spyOn(process, \"cwd\").mockImplementation(() => TEST_DIR);\n      const targetPath = path.join(process.cwd(), \"schema.graphql\");\n      await buildSchema({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: true,\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should read EmitSchemaFileOptions and apply them in emit\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test4\", \"schema.graphql\");\n      await buildSchema({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: {\n          path: targetPath,\n          sortedSchema: false,\n        },\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), {\n        sortedSchema: false,\n      });\n    });\n\n    it(\"should read EmitSchemaFileOptions and set default path and sorting schema\", async () => {\n      jest.spyOn(process, \"cwd\").mockImplementation(() => TEST_DIR);\n      const targetPath = path.join(process.cwd(), \"schema.graphql\");\n      await buildSchema({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: {},\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), {\n        ...defaultPrintSchemaOptions,\n      });\n    });\n  });\n\n  describe(\"buildSchemaSync\", () => {\n    it(\"should synchronously generate schema SDL file on selected file path\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test5\", \"schema.graphql\");\n      buildSchemaSync({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: targetPath,\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should generate schema SDL file in current working dir\", async () => {\n      jest.spyOn(process, \"cwd\").mockImplementation(() => TEST_DIR);\n      const targetPath = path.join(process.cwd(), \"schema.graphql\");\n      buildSchemaSync({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: true,\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString());\n    });\n\n    it(\"should read EmitSchemaFileOptions and apply them in emit\", async () => {\n      const targetPath = path.join(TEST_DIR, \"schemas\", \"test6\", \"schema.graphql\");\n      buildSchemaSync({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: {\n          path: targetPath,\n          sortedSchema: false,\n        },\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), {\n        sortedSchema: false,\n      });\n    });\n\n    it(\"should read EmitSchemaFileOptions and set default path and sorting schema\", async () => {\n      jest.spyOn(process, \"cwd\").mockImplementation(() => TEST_DIR);\n      const targetPath = path.join(process.cwd(), \"schema.graphql\");\n      buildSchemaSync({\n        resolvers: [MyResolverClass],\n        emitSchemaFile: {},\n      });\n      expect(fs.existsSync(targetPath)).toEqual(true);\n      checkSchemaSDL(fs.readFileSync(targetPath).toString(), {\n        ...defaultPrintSchemaOptions,\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/enums.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionEnumType,\n  type IntrospectionInputObjectType,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport { Arg, Field, InputType, Query, registerEnumType } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport {\n  getInnerInputFieldType,\n  getInnerTypeOfNonNullableType,\n} from \"../helpers/getInnerFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Enums\", () => {\n  let schemaIntrospection: IntrospectionSchema;\n  let queryType: IntrospectionObjectType;\n  let schema: GraphQLSchema;\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    enum NumberEnum {\n      One = 1,\n      Two,\n      Three,\n      Four,\n    }\n    registerEnumType(NumberEnum, { name: \"NumberEnum\" });\n\n    enum StringEnum {\n      One = \"ONE\",\n      Two = \"TWO\",\n      Three = \"THREE\",\n    }\n    registerEnumType(StringEnum, { name: \"StringEnum\", description: \"custom string enum\" });\n\n    enum AdvancedEnum {\n      DescriptionProperty = \"DescriptionProperty\",\n      DeprecationProperty = \"DeprecationProperty\",\n    }\n    registerEnumType(AdvancedEnum, {\n      name: \"AdvancedEnum\",\n      valuesConfig: {\n        DescriptionProperty: { description: \"One field description\" },\n        DeprecationProperty: { deprecationReason: \"Two field deprecation reason\" },\n      },\n    });\n\n    @InputType()\n    class NumberEnumInput {\n      @Field(() => NumberEnum)\n      numberEnumField!: NumberEnum;\n    }\n\n    @InputType()\n    class StringEnumInput {\n      @Field(() => StringEnum)\n      stringEnumField!: StringEnum;\n    }\n\n    class SampleResolver {\n      @Query(_returns => NumberEnum)\n      getNumberEnumValue(@Arg(\"input\") _input: NumberEnumInput): NumberEnum {\n        return NumberEnum.Two;\n      }\n\n      @Query(() => StringEnum)\n      getStringEnumValue(@Arg(\"input\") _input: StringEnumInput): StringEnum {\n        return StringEnum.Two;\n      }\n\n      @Query(() => AdvancedEnum)\n      getAdvancedEnumValue(): AdvancedEnum {\n        return AdvancedEnum.DescriptionProperty;\n      }\n\n      @Query()\n      isNumberEnumEqualOne(@Arg(\"enum\", () => NumberEnum) numberEnum: NumberEnum): boolean {\n        return numberEnum === NumberEnum.One;\n      }\n\n      @Query()\n      isStringEnumEqualOne(@Arg(\"enum\", () => StringEnum) stringEnum: StringEnum): boolean {\n        return stringEnum === StringEnum.One;\n      }\n    }\n\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [SampleResolver],\n    });\n    schema = schemaInfo.schema;\n    schemaIntrospection = schemaInfo.schemaIntrospection;\n    queryType = schemaInfo.queryType;\n  });\n\n  describe(\"Schema\", () => {\n    it(\"should generate schema without errors\", async () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    it(\"should generate correct enum output type\", async () => {\n      const getNumberEnumValueType = getInnerTypeOfNonNullableType(\n        queryType.fields.find(field => field.name === \"getNumberEnumValue\")!,\n      );\n      const getStringEnumValue = getInnerTypeOfNonNullableType(\n        queryType.fields.find(field => field.name === \"getStringEnumValue\")!,\n      );\n\n      expect(getNumberEnumValueType.kind).toEqual(TypeKind.ENUM);\n      expect(getNumberEnumValueType.name).toEqual(\"NumberEnum\");\n      expect(getStringEnumValue.kind).toEqual(TypeKind.ENUM);\n      expect(getStringEnumValue.name).toEqual(\"StringEnum\");\n    });\n\n    it(\"should generate correct enum input type\", async () => {\n      const numberEnumInput = schemaIntrospection.types.find(\n        type => type.kind === \"INPUT_OBJECT\" && type.name === \"NumberEnumInput\",\n      ) as IntrospectionInputObjectType;\n      const stringEnumInput = schemaIntrospection.types.find(\n        type => type.kind === \"INPUT_OBJECT\" && type.name === \"StringEnumInput\",\n      ) as IntrospectionInputObjectType;\n      const numberEnumInputType = getInnerInputFieldType(numberEnumInput, \"numberEnumField\");\n      const stringEnumInputType = getInnerInputFieldType(stringEnumInput, \"stringEnumField\");\n\n      expect(numberEnumInputType.kind).toEqual(TypeKind.ENUM);\n      expect(numberEnumInputType.name).toEqual(\"NumberEnum\");\n      expect(stringEnumInputType.kind).toEqual(TypeKind.ENUM);\n      expect(stringEnumInputType.name).toEqual(\"StringEnum\");\n    });\n\n    it(\"should generate correct enum arg type\", async () => {\n      const numberEnumArgType = getInnerTypeOfNonNullableType(\n        queryType.fields.find(type => type.name === \"isNumberEnumEqualOne\")!.args[0],\n      );\n      const stringEnumArgType = getInnerTypeOfNonNullableType(\n        queryType.fields.find(type => type.name === \"isStringEnumEqualOne\")!.args[0],\n      );\n\n      expect(numberEnumArgType.kind).toEqual(TypeKind.ENUM);\n      expect(numberEnumArgType.name).toEqual(\"NumberEnum\");\n      expect(stringEnumArgType.kind).toEqual(TypeKind.ENUM);\n      expect(stringEnumArgType.name).toEqual(\"StringEnum\");\n    });\n\n    it(\"should generate correct enum values for number enum\", async () => {\n      const numberEnumType = schemaIntrospection.types.find(\n        type => type.kind === \"ENUM\" && type.name === \"NumberEnum\",\n      ) as IntrospectionEnumType;\n\n      expect(numberEnumType.name).toEqual(\"NumberEnum\");\n      expect(numberEnumType.kind).toEqual(TypeKind.ENUM);\n      expect(numberEnumType.enumValues).toHaveLength(4);\n      expect(numberEnumType.enumValues[0].name).toEqual(\"One\");\n      expect(numberEnumType.enumValues[1].name).toEqual(\"Two\");\n      expect(numberEnumType.enumValues[2].name).toEqual(\"Three\");\n      expect(numberEnumType.enumValues[3].name).toEqual(\"Four\");\n    });\n\n    it(\"should generate correct enum values for string enum\", async () => {\n      const stringEnumType = schemaIntrospection.types.find(\n        type => type.kind === \"ENUM\" && type.name === \"StringEnum\",\n      ) as IntrospectionEnumType;\n\n      expect(stringEnumType.name).toEqual(\"StringEnum\");\n      expect(stringEnumType.kind).toEqual(TypeKind.ENUM);\n      expect(stringEnumType.description).toEqual(\"custom string enum\");\n      expect(stringEnumType.enumValues).toHaveLength(3);\n      expect(stringEnumType.enumValues[0].name).toEqual(\"One\");\n      expect(stringEnumType.enumValues[1].name).toEqual(\"Two\");\n      expect(stringEnumType.enumValues[2].name).toEqual(\"Three\");\n    });\n\n    it(\"should generate correct enum descriptions\", async () => {\n      const advancedEnumType = schemaIntrospection.types.find(\n        type => type.kind === \"ENUM\" && type.name === \"AdvancedEnum\",\n      ) as IntrospectionEnumType;\n\n      expect(advancedEnumType.name).toEqual(\"AdvancedEnum\");\n      expect(advancedEnumType.kind).toEqual(TypeKind.ENUM);\n      expect(advancedEnumType.enumValues).toHaveLength(2);\n      expect(advancedEnumType.enumValues[0].name).toEqual(\"DescriptionProperty\");\n      expect(advancedEnumType.enumValues[0].description).toEqual(\"One field description\");\n    });\n\n    it(\"should generate correct enum deprecation reason\", async () => {\n      const advancedEnumType = schemaIntrospection.types.find(\n        type => type.kind === \"ENUM\" && type.name === \"AdvancedEnum\",\n      ) as IntrospectionEnumType;\n\n      expect(advancedEnumType.name).toEqual(\"AdvancedEnum\");\n      expect(advancedEnumType.kind).toEqual(TypeKind.ENUM);\n      expect(advancedEnumType.enumValues).toHaveLength(2);\n      expect(advancedEnumType.enumValues[1].name).toEqual(\"DeprecationProperty\");\n      expect(advancedEnumType.enumValues[1].isDeprecated).toEqual(true);\n      expect(advancedEnumType.enumValues[1].deprecationReason).toEqual(\n        \"Two field deprecation reason\",\n      );\n    });\n  });\n\n  describe(\"Functional\", () => {\n    it(\"should correctly serialize number enum internal value\", async () => {\n      const query = `query {\n        getNumberEnumValue(input: { numberEnumField: One })\n      }`;\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data!.getNumberEnumValue).toEqual(\"Two\");\n    });\n\n    it(\"should correctly serialize string enum internal value\", async () => {\n      const query = `query {\n        getStringEnumValue(input: { stringEnumField: One })\n      }`;\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data!.getStringEnumValue).toEqual(\"Two\");\n    });\n\n    it(\"should correctly map number enum to internal value\", async () => {\n      const query1 = `query {\n        isNumberEnumEqualOne(enum: One)\n      }`;\n      const query2 = `query {\n        isNumberEnumEqualOne(enum: Two)\n      }`;\n\n      const result1 = await graphql({ schema, source: query1 });\n      const result2 = await graphql({ schema, source: query2 });\n\n      expect(result1.data!.isNumberEnumEqualOne).toEqual(true);\n      expect(result2.data!.isNumberEnumEqualOne).toEqual(false);\n    });\n\n    it(\"should correctly map string enum to internal value\", async () => {\n      const query1 = `query {\n        isStringEnumEqualOne(enum: One)\n      }`;\n      const query2 = `query {\n        isStringEnumEqualOne(enum: Two)\n      }`;\n\n      const result1 = await graphql({ schema, source: query1 });\n      const result2 = await graphql({ schema, source: query2 });\n\n      expect(result1.data!.isStringEnumEqualOne).toEqual(true);\n      expect(result2.data!.isStringEnumEqualOne).toEqual(false);\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/errors/metadata-polyfill.ts",
    "content": "import { ReflectMetadataMissingError } from \"type-graphql\";\nimport { findType } from \"@/helpers/findType\";\nimport { expectToThrow } from \"../../helpers/expectToThrow\";\n\ndescribe(\"Reflect metadata\", () => {\n  it(\"should throw ReflectMetadataMissingError when no polyfill provided\", async () => {\n    const error = await expectToThrow(() =>\n      findType({\n        metadataKey: \"design:type\",\n        prototype: {},\n        propertyKey: \"test\",\n      }),\n    );\n\n    expect(error).toBeInstanceOf(ReflectMetadataMissingError);\n    expect(error.message).toContain(\"metadata\");\n    expect(error.message).toContain(\"polyfill\");\n  });\n});\n"
  },
  {
    "path": "tests/functional/extensions.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLFieldMap,\n  type GraphQLInputObjectType,\n  GraphQLInterfaceType,\n  type GraphQLObjectType,\n  type GraphQLSchema,\n} from \"graphql\";\nimport {\n  Arg,\n  Extensions,\n  Field,\n  FieldResolver,\n  InputType,\n  InterfaceType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"Extensions\", () => {\n  let schema: GraphQLSchema;\n\n  describe(\"Schema\", () => {\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @InputType()\n      class ExtensionsOnFieldInput {\n        @Field()\n        @Extensions({ role: \"admin\" })\n        withExtensions!: string;\n      }\n\n      @InputType()\n      @Extensions({ roles: [\"admin\", \"user\"] })\n      class ExtensionsOnClassInput {\n        @Field()\n        regularField!: string;\n      }\n\n      @ObjectType()\n      @Extensions({ id: 1234 })\n      class ExtensionsOnClassObjectType {\n        @Field()\n        regularField!: string;\n      }\n\n      @ObjectType()\n      class SampleObjectType {\n        @Field()\n        @Extensions({ role: \"user\" })\n        withExtensions: string = \"withExtensions\";\n\n        @Field()\n        @Extensions({ first: \"first value\", second: \"second value\" })\n        withMultipleExtensions: string = \"withMultipleExtensions\";\n\n        @Field()\n        @Extensions({ first: \"first value\" })\n        @Extensions({ second: \"second value\", third: \"third value\" })\n        withMultipleExtensionsDecorators: string = \"hello\";\n\n        @Field()\n        @Extensions({ duplicate: \"first value\" })\n        @Extensions({ duplicate: \"second value\" })\n        withConflictingExtensionsKeys: string = \"hello\";\n\n        @Field()\n        withInput(@Arg(\"input\") input: ExtensionsOnFieldInput): string {\n          return `hello${input.withExtensions}`;\n        }\n\n        @Field()\n        @Extensions({ other: \"extension\" })\n        withInputAndField(@Arg(\"input\") input: ExtensionsOnFieldInput): string {\n          return `hello${input.withExtensions}`;\n        }\n\n        @Field()\n        withInputOnClass(@Arg(\"input\") input: ExtensionsOnClassInput): string {\n          return `hello${input.regularField}`;\n        }\n\n        @Field()\n        @Extensions({ other: \"extension\" })\n        withInputAndFieldOnClass(@Arg(\"input\") input: ExtensionsOnClassInput): string {\n          return `hello${input.regularField}`;\n        }\n      }\n\n      @InterfaceType()\n      @Extensions({ meta: \"interfaceExtensionData\" })\n      class SampleInterfaceType {\n        @Field()\n        @Extensions({ meta: \"interfaceFieldExtensionData\" })\n        withInterfaceFieldExtension!: string;\n      }\n\n      @ObjectType({\n        implements: [SampleInterfaceType],\n      })\n      class SampleObjectInterfaceImplementation extends SampleInterfaceType {}\n\n      @InterfaceType({\n        implements: [SampleInterfaceType],\n      })\n      class SampleInterfaceInterfaceImplementation extends SampleInterfaceType {}\n\n      @ObjectType({\n        implements: [SampleInterfaceInterfaceImplementation],\n      })\n      class SampleObjectInterfaceInterfaceImplementation extends SampleInterfaceInterfaceImplementation {}\n\n      @Resolver()\n      class SampleResolver {\n        @Query(() => SampleObjectType)\n        sampleObjectType(): SampleObjectType {\n          return new SampleObjectType();\n        }\n\n        @Query(() => ExtensionsOnClassObjectType)\n        extensionsOnClassObjectType(): ExtensionsOnClassObjectType {\n          return new ExtensionsOnClassObjectType();\n        }\n\n        @Query(() => SampleObjectInterfaceImplementation)\n        sampleObjectInterfaceImplementation(): SampleObjectInterfaceImplementation {\n          return new SampleObjectInterfaceImplementation();\n        }\n\n        @Query(() => SampleInterfaceInterfaceImplementation)\n        sampleInterfaceInterfaceImplementation(): SampleInterfaceInterfaceImplementation {\n          return new SampleInterfaceInterfaceImplementation();\n        }\n\n        @Query(() => SampleObjectInterfaceInterfaceImplementation)\n        sampleObjectInterfaceInterfaceImplementation(): SampleObjectInterfaceInterfaceImplementation {\n          return new SampleObjectInterfaceInterfaceImplementation();\n        }\n\n        @Query(() => SampleInterfaceType)\n        sampleInterfaceType(): SampleInterfaceType {\n          return new SampleObjectInterfaceImplementation();\n        }\n\n        @Query()\n        @Extensions({ mandatory: true })\n        queryWithExtensions(): string {\n          return \"queryWithExtensions\";\n        }\n\n        @Query()\n        @Extensions({ first: \"first query value\", second: \"second query value\" })\n        queryWithMultipleExtensions(): string {\n          return \"hello\";\n        }\n\n        @Query()\n        @Extensions({ first: \"first query value\" })\n        @Extensions({ second: \"second query value\", third: \"third query value\" })\n        queryWithMultipleExtensionsDecorators(): string {\n          return \"hello\";\n        }\n\n        @Mutation()\n        @Extensions({ mandatory: false })\n        mutationWithExtensions(): string {\n          return \"mutationWithExtensions\";\n        }\n\n        @Mutation()\n        @Extensions({ first: \"first mutation value\", second: \"second mutation value\" })\n        mutationWithMultipleExtensions(): string {\n          return \"mutationWithMultipleExtensions\";\n        }\n\n        @Mutation()\n        @Extensions({ first: \"first mutation value\" })\n        @Extensions({ second: \"second mutation value\", third: \"third mutation value\" })\n        mutationWithMultipleExtensionsDecorators(): string {\n          return \"mutationWithMultipleExtensionsDecorators\";\n        }\n      }\n\n      @Resolver(() => SampleObjectType)\n      class SampleObjectTypeResolver {\n        @FieldResolver()\n        @Extensions({ some: \"extension\" })\n        fieldResolverWithExtensions(): string {\n          return \"hello\";\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver, SampleObjectTypeResolver],\n      });\n    });\n\n    it(\"should generate schema without errors\", async () => {\n      expect(schema).toBeDefined();\n    });\n\n    describe(\"Fields\", () => {\n      let fields: GraphQLFieldMap<any, any>;\n\n      beforeAll(async () => {\n        fields = (schema.getType(\"SampleObjectType\") as GraphQLObjectType).getFields();\n      });\n\n      it(\"should add simple extensions to object fields\", async () => {\n        expect(fields.withExtensions.extensions).toEqual({ role: \"user\" });\n      });\n\n      it(\"should add extensions with multiple properties to object fields\", async () => {\n        expect(fields.withMultipleExtensions.extensions).toEqual({\n          first: \"first value\",\n          second: \"second value\",\n        });\n      });\n\n      it(\"should allow multiple extensions decorators for object fields\", async () => {\n        expect(fields.withMultipleExtensionsDecorators.extensions).toEqual({\n          first: \"first value\",\n          second: \"second value\",\n          third: \"third value\",\n        });\n      });\n\n      it(\"should override extensions values when duplicate keys are provided\", async () => {\n        expect(fields.withConflictingExtensionsKeys.extensions).toEqual({\n          duplicate: \"second value\",\n        });\n      });\n    });\n\n    describe(\"Query\", () => {\n      it(\"should add simple extensions to query types\", async () => {\n        const { queryWithExtensions } = schema.getQueryType()!.getFields();\n        expect(queryWithExtensions.extensions).toEqual({ mandatory: true });\n      });\n\n      it(\"should add extensions with multiple properties to query types\", async () => {\n        const { queryWithMultipleExtensions } = schema.getQueryType()!.getFields();\n        expect(queryWithMultipleExtensions.extensions).toEqual({\n          first: \"first query value\",\n          second: \"second query value\",\n        });\n      });\n\n      it(\"should allow multiple extensions decorators for query types\", async () => {\n        const { queryWithMultipleExtensionsDecorators } = schema.getQueryType()!.getFields();\n        expect(queryWithMultipleExtensionsDecorators.extensions).toEqual({\n          first: \"first query value\",\n          second: \"second query value\",\n          third: \"third query value\",\n        });\n      });\n    });\n\n    describe(\"Mutation\", () => {\n      it(\"should add simple extensions to mutation types\", async () => {\n        const { mutationWithExtensions } = schema.getMutationType()!.getFields();\n        expect(mutationWithExtensions.extensions).toEqual({ mandatory: false });\n      });\n\n      it(\"should add extensions with multiple properties to mutation types\", async () => {\n        const { mutationWithMultipleExtensions } = schema.getMutationType()!.getFields();\n        expect(mutationWithMultipleExtensions.extensions).toEqual({\n          first: \"first mutation value\",\n          second: \"second mutation value\",\n        });\n      });\n\n      it(\"should allow multiple extensions decorators for mutation types\", async () => {\n        const { mutationWithMultipleExtensionsDecorators } = schema.getMutationType()!.getFields();\n        expect(mutationWithMultipleExtensionsDecorators.extensions).toEqual({\n          first: \"first mutation value\",\n          second: \"second mutation value\",\n          third: \"third mutation value\",\n        });\n      });\n    });\n\n    describe(\"ObjectType\", () => {\n      it(\"should add extensions to object types\", async () => {\n        const objectType = schema.getType(\"ExtensionsOnClassObjectType\") as GraphQLObjectType;\n        expect(objectType.extensions).toEqual({ id: 1234 });\n      });\n    });\n\n    describe(\"InputType\", () => {\n      it(\"should add extensions to input types\", async () => {\n        const inputType = schema.getType(\"ExtensionsOnClassInput\") as GraphQLInputObjectType;\n        expect(inputType.extensions).toEqual({ roles: [\"admin\", \"user\"] });\n      });\n\n      it(\"should add extensions to input type fields\", async () => {\n        const fields = (\n          schema.getType(\"ExtensionsOnFieldInput\") as GraphQLInputObjectType\n        ).getFields();\n\n        expect(fields.withExtensions.extensions).toEqual({ role: \"admin\" });\n      });\n    });\n\n    describe(\"FieldResolver\", () => {\n      it(\"should add extensions to field resolvers\", async () => {\n        const fields = (schema.getType(\"SampleObjectType\") as GraphQLObjectType).getFields();\n        expect(fields.fieldResolverWithExtensions.extensions).toEqual({ some: \"extension\" });\n      });\n    });\n\n    describe(\"Interface Fields\", () => {\n      it(\"should add extensions to interface types\", async () => {\n        const fields = (schema.getType(\"SampleInterfaceType\") as GraphQLObjectType).getFields();\n        expect(fields.withInterfaceFieldExtension.extensions).toEqual({\n          meta: \"interfaceFieldExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to ObjectType which extends InterfaceType\", async () => {\n        const fields = (\n          schema.getType(\"SampleObjectInterfaceImplementation\") as GraphQLObjectType\n        ).getFields();\n        expect(fields.withInterfaceFieldExtension.extensions).toEqual({\n          meta: \"interfaceFieldExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to Interface which extends InterfaceType\", async () => {\n        const fields = (\n          schema.getType(\"SampleInterfaceInterfaceImplementation\") as GraphQLObjectType\n        ).getFields();\n        expect(fields.withInterfaceFieldExtension.extensions).toEqual({\n          meta: \"interfaceFieldExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to ObjectType which extends InterfaceType which extends InterfaceType\", async () => {\n        const fields = (\n          schema.getType(\"SampleInterfaceInterfaceImplementation\") as GraphQLObjectType\n        ).getFields();\n        expect(fields.withInterfaceFieldExtension.extensions).toEqual({\n          meta: \"interfaceFieldExtensionData\",\n        });\n      });\n    });\n\n    describe(\"Interface Class\", () => {\n      it(\"should add extensions to interface types\", async () => {\n        const sampleInterface = schema.getType(\"SampleInterfaceType\") as GraphQLInterfaceType;\n        expect(sampleInterface.extensions).toEqual({\n          meta: \"interfaceExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to ObjectType which extends InterfaceType\", async () => {\n        const sampleInterface = schema.getType(\n          \"SampleObjectInterfaceImplementation\",\n        ) as GraphQLInterfaceType;\n        expect(sampleInterface.extensions).toEqual({\n          meta: \"interfaceExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to InterfaceType which extends InterfaceType\", async () => {\n        const sampleInterface = schema.getType(\n          \"SampleInterfaceInterfaceImplementation\",\n        ) as GraphQLInterfaceType;\n        expect(sampleInterface.extensions).toEqual({\n          meta: \"interfaceExtensionData\",\n        });\n      });\n\n      it(\"should add extensions to ObjectType which extends InterfaceType which extends InterfaceType\", async () => {\n        const sampleInterface = schema.getType(\n          \"SampleObjectInterfaceInterfaceImplementation\",\n        ) as GraphQLInterfaceType;\n        expect(sampleInterface.extensions).toEqual({\n          meta: \"interfaceExtensionData\",\n        });\n      });\n    });\n\n    describe(\"Inheritance\", () => {\n      beforeAll(async () => {\n        getMetadataStorage().clear();\n\n        @ObjectType()\n        @Extensions({ parentClass: true })\n        class Parent {\n          @Field()\n          @Extensions({ parentField: true })\n          parentField!: string;\n        }\n        @Extensions({ childClass: true })\n        @ObjectType()\n        class Child extends Parent {\n          @Field()\n          @Extensions({ childField: true })\n          childField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): Child {\n            return {} as Child;\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [SampleResolver],\n          orphanedTypes: [Parent],\n        });\n      });\n\n      it(\"should inherit object type extensions from parent object type class\", () => {\n        const childObjectType = schema.getType(\"Child\") as GraphQLObjectType;\n\n        expect(childObjectType.extensions).toEqual({\n          parentClass: true,\n          childClass: true,\n        });\n      });\n\n      it(\"should not get object type extensions from child object type class\", () => {\n        const parentObjectType = schema.getType(\"Parent\") as GraphQLObjectType;\n\n        expect(parentObjectType.extensions).toEqual({\n          parentClass: true,\n        });\n      });\n\n      it(\"should inherit object type field extensions from parent object type field\", () => {\n        const childObjectType = schema.getType(\"Child\") as GraphQLObjectType;\n        const childObjectTypeParentField = childObjectType.getFields().parentField;\n\n        expect(childObjectTypeParentField.extensions).toEqual({ parentField: true });\n      });\n    });\n\n    describe(\"Fields with field resolvers\", () => {\n      beforeAll(async () => {\n        getMetadataStorage().clear();\n\n        @ObjectType()\n        class Child {\n          @Field()\n          @Extensions({ childField: true })\n          childField!: string;\n        }\n        @Resolver(() => Child)\n        class ChildResolver {\n          @Query()\n          sampleQuery(): Child {\n            return {} as Child;\n          }\n\n          @Extensions({ childFieldResolver: true })\n          @FieldResolver()\n          childField(): string {\n            return \"childField\";\n          }\n        }\n\n        schema = await buildSchema({\n          resolvers: [ChildResolver],\n        });\n      });\n\n      it(\"should merge field level with field resolver level extensions\", () => {\n        const childObjectType = schema.getType(\"Child\") as GraphQLObjectType;\n\n        expect(childObjectType.getFields().childField.extensions).toEqual({\n          childField: true,\n          childFieldResolver: true,\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/fields.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type IntrospectionListTypeRef,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionScalarType,\n  type IntrospectionSchema,\n  TypeKind,\n} from \"graphql\";\nimport { Field, GraphQLISODateTime, ObjectType, Query, Resolver } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Fields - schema\", () => {\n  let schemaIntrospection: IntrospectionSchema;\n  let sampleObjectType: IntrospectionObjectType;\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    @ObjectType()\n    class SampleNestedObject {\n      @Field()\n      stringField!: string;\n    }\n\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      implicitStringField!: string;\n\n      @Field(() => String)\n      explicitStringField: any;\n\n      @Field()\n      implicitObjectField!: SampleNestedObject;\n\n      @Field(() => String, { nullable: true })\n      explicitNullableStringField: any;\n\n      @Field({ nullable: true })\n      implicitNullableStringField!: string;\n\n      @Field(() => [String])\n      explicitStringArrayField!: string[];\n\n      @Field(() => [String], { nullable: true })\n      nullableArrayFieldNew!: string[] | null;\n\n      @Field(() => [SampleNestedObject], { nullable: true })\n      nullableObjectArrayField!: SampleNestedObject[] | null;\n\n      @Field(() => [String], { nullable: \"itemsAndList\" })\n      arrayWithNullableItemField!: string[];\n\n      @Field(() => [String], { nullable: \"items\" })\n      nonNullArrayWithNullableItemField!: string[];\n\n      @Field({ name: \"overwrittenName\", nullable: true })\n      overwrittenStringField!: string;\n\n      @Field({ name: \"complexField\", complexity: 10 })\n      complexField!: string;\n\n      @Field(() => [[String]], { nullable: true })\n      nullableNestedArrayField!: string[][] | null;\n\n      @Field(() => [[String]], { nullable: \"items\" })\n      nonNullNestedArrayWithNullableItemField!: Array<Array<string | null> | null>;\n\n      @Field(() => [[String]], { nullable: \"itemsAndList\" })\n      nestedArrayWithNullableItemField!: Array<Array<string | null> | null> | null;\n\n      @Field(() => GraphQLISODateTime)\n      overwrittenArrayScalarField!: string[];\n    }\n\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      @Query()\n      sampleQuery(): SampleObject {\n        return {} as SampleObject;\n      }\n    }\n\n    // get builded schema info from retrospection\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [SampleResolver],\n    });\n    schemaIntrospection = schemaInfo.schemaIntrospection;\n    sampleObjectType = schemaIntrospection.types.find(\n      type => type.name === \"SampleObject\",\n    ) as IntrospectionObjectType;\n  });\n\n  // helpers\n  function getInnerFieldType(name: string) {\n    const fieldType = sampleObjectType.fields.find(field => field.name === name)!;\n    return (fieldType.type as IntrospectionNonNullTypeRef).ofType! as IntrospectionNamedTypeRef;\n  }\n\n  // tests\n  it(\"should generate schema without errors\", async () => {\n    expect(schemaIntrospection).toBeDefined();\n  });\n\n  it(\"should register complexity info for field\", async () => {\n    const metadataStorage = getMetadataStorage();\n    const sampleObj = metadataStorage.objectTypes.find(it => it.name === \"SampleObject\")!;\n    const complexField = sampleObj.fields!.find(it => it.name === \"complexField\")!;\n    expect(complexField.complexity).toBe(10);\n  });\n\n  it(\"should throw error when field type not provided\", async () => {\n    getMetadataStorage().clear();\n\n    const error = await expectToThrow(() => {\n      @ObjectType()\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObject {\n        @Field()\n        invalidSampleField: any;\n      }\n    });\n\n    expect(error).toBeInstanceOf(Error);\n    expect(error.message).toContain(\"provide explicit type\");\n    expect(error.message).toContain(\"invalidSampleField\");\n  });\n\n  it(\"should throw error when field type is array and no explicit type provided\", async () => {\n    getMetadataStorage().clear();\n\n    const error = await expectToThrow(() => {\n      @ObjectType()\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObject {\n        @Field()\n        invalidSampleArrayField!: string[];\n      }\n    });\n\n    expect(error).toBeInstanceOf(Error);\n    expect(error.message).toContain(\"provide explicit type\");\n    expect(error.message).toContain(\"invalidSampleArrayField\");\n  });\n\n  it(\"should throw error when cannot determine field type\", async () => {\n    getMetadataStorage().clear();\n\n    const error = await expectToThrow(() => {\n      @ObjectType()\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObject {\n        @Field({ nullable: true })\n        invalidSampleNullableField!: string | null;\n      }\n    });\n\n    expect(error).toBeInstanceOf(Error);\n    expect(error.message).toContain(\"provide explicit type\");\n    expect(error.message).toContain(\"invalidSampleNullableField\");\n  });\n\n  it(\"should throw error when object type property key is symbol\", async () => {\n    getMetadataStorage().clear();\n\n    const symbolKey = Symbol(\"symbolKey\");\n    const error = await expectToThrow(() => {\n      @ObjectType()\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObject {\n        @Field({ nullable: true })\n        [symbolKey]!: string | null;\n      }\n    });\n\n    expect(error.message).toContain(\"Symbol keys are not supported yet!\");\n  });\n\n  it(\"should generate non-nullable field type by default\", async () => {\n    const implicitStringField = sampleObjectType.fields.find(\n      field => field.name === \"implicitStringField\",\n    )!;\n\n    expect(implicitStringField.type.kind).toEqual(TypeKind.NON_NULL);\n  });\n\n  it(\"should generate implicit field type for scalar\", async () => {\n    const implicitStringFieldType = getInnerFieldType(\"implicitStringField\");\n\n    expect(implicitStringFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(implicitStringFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate explicit field type for scalar\", async () => {\n    const explicitStringFieldType = getInnerFieldType(\"explicitStringField\");\n\n    expect(explicitStringFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(explicitStringFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate implicit field type for object type\", async () => {\n    const implicitObjectFieldType = getInnerFieldType(\"implicitObjectField\");\n\n    expect(implicitObjectFieldType.kind).toEqual(TypeKind.OBJECT);\n    expect(implicitObjectFieldType.name).toEqual(\"SampleNestedObject\");\n  });\n\n  it(\"should generate nullable field type for implicit scalar\", async () => {\n    const implicitNullableStringField = sampleObjectType.fields.find(\n      field => field.name === \"implicitNullableStringField\",\n    )!;\n    // prettier-ignore\n    const implicitNullableStringFieldType =\n      implicitNullableStringField.type as IntrospectionNamedTypeRef;\n\n    expect(implicitNullableStringFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(implicitNullableStringFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable field type for explicit type\", async () => {\n    const explicitNullableStringField = sampleObjectType.fields.find(\n      field => field.name === \"explicitNullableStringField\",\n    )!;\n    // prettier-ignore\n    const explicitNullableStringFieldType =\n      explicitNullableStringField.type as IntrospectionNamedTypeRef;\n\n    expect(explicitNullableStringFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(explicitNullableStringFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate non-nullable array of non-nullable items field type by default\", async () => {\n    const nonNullField = sampleObjectType.fields.find(\n      field => field.name === \"explicitStringArrayField\",\n    )!;\n    const nonNullFieldType = nonNullField.type as IntrospectionNonNullTypeRef;\n    const arrayFieldType = nonNullFieldType.ofType as IntrospectionListTypeRef;\n    const arrayItemNonNullFieldType = arrayFieldType.ofType as IntrospectionNonNullTypeRef;\n    const arrayItemFieldType = arrayItemNonNullFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(nonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(arrayItemFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable array field type when declared using mongoose syntax\", async () => {\n    const nullableArrayFieldNew = sampleObjectType.fields.find(\n      field => field.name === \"nullableArrayFieldNew\",\n    )!;\n    const arrayFieldType = nullableArrayFieldNew.type as IntrospectionListTypeRef;\n    const arrayItemNonNullFieldType = arrayFieldType.ofType as IntrospectionNonNullTypeRef;\n    const arrayItemFieldType = arrayItemNonNullFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(arrayFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(arrayItemFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable array field object type when declared using mongoose syntax\", async () => {\n    const nullableArrayFieldNew = sampleObjectType.fields.find(\n      field => field.name === \"nullableObjectArrayField\",\n    )!;\n    const arrayFieldType = nullableArrayFieldNew.type as IntrospectionListTypeRef;\n    const arrayItemNonNullFieldType = arrayFieldType.ofType as IntrospectionNonNullTypeRef;\n    const arrayItemFieldType = arrayItemNonNullFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(arrayFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.OBJECT);\n    expect(arrayItemFieldType.name).toEqual(\"SampleNestedObject\");\n  });\n\n  it(\"should generate nullable item array with nullable option 'itemAndList'\", async () => {\n    const arrayWithNullableItemField = sampleObjectType.fields.find(\n      field => field.name === \"arrayWithNullableItemField\",\n    )!;\n    const nullableArrayType = arrayWithNullableItemField.type as IntrospectionListTypeRef;\n    const nullableItemType = nullableArrayType.ofType as IntrospectionNamedTypeRef;\n\n    expect(nullableArrayType.kind).toEqual(TypeKind.LIST);\n    expect(nullableItemType.kind).toEqual(TypeKind.SCALAR);\n    expect(nullableItemType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable element nonNull array with nullable option 'item'\", async () => {\n    const nonNullArrayWithNullableItemField = sampleObjectType.fields.find(\n      field => field.name === \"nonNullArrayWithNullableItemField\",\n    )!;\n    const nonNullArrayType = nonNullArrayWithNullableItemField.type as IntrospectionNonNullTypeRef;\n    const arrayType = nonNullArrayType.ofType as IntrospectionListTypeRef;\n    const elementType = arrayType.ofType as IntrospectionNamedTypeRef;\n\n    expect(nonNullArrayType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayType.kind).toEqual(TypeKind.LIST);\n    expect(elementType.kind).toEqual(TypeKind.SCALAR);\n    expect(elementType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate field with overwritten name from decorator option\", async () => {\n    const overwrittenNameField = sampleObjectType.fields.find(\n      field => field.name === \"overwrittenName\",\n    )!;\n    const overwrittenStringField = sampleObjectType.fields.find(\n      field => field.name === \"overwrittenStringField\",\n    );\n    const overwrittenNameFieldType = overwrittenNameField.type as IntrospectionNamedTypeRef;\n\n    expect(overwrittenStringField).toBeUndefined();\n    expect(overwrittenNameFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(overwrittenNameFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable nested array field type when declared using mongoose syntax\", async () => {\n    const nullableNestedArrayField = sampleObjectType.fields.find(\n      field => field.name === \"nullableNestedArrayField\",\n    )!;\n    const arrayFieldType = nullableNestedArrayField.type as IntrospectionListTypeRef;\n    const arrayItemNonNullFieldType = arrayFieldType.ofType as IntrospectionNonNullTypeRef;\n    const arrayItemFieldType = arrayItemNonNullFieldType.ofType as IntrospectionListTypeRef;\n    const arrayItemScalarNonNullFieldType =\n      arrayItemFieldType.ofType as IntrospectionNonNullTypeRef;\n    const arrayItemScalarFieldType =\n      arrayItemScalarNonNullFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(arrayFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemScalarNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemScalarFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(arrayItemScalarFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nested array with nullable option 'items'\", async () => {\n    const nestedArrayField = sampleObjectType.fields.find(\n      field => field.name === \"nonNullNestedArrayWithNullableItemField\",\n    )!;\n\n    const arrayNonNullFieldType = nestedArrayField.type as IntrospectionNonNullTypeRef;\n    const arrayItemFieldType = arrayNonNullFieldType.ofType as IntrospectionListTypeRef;\n    const arrayItemInnerFieldType = arrayItemFieldType.ofType as IntrospectionListTypeRef;\n    const arrayItemScalarFieldType = arrayItemInnerFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(arrayNonNullFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemInnerFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemScalarFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(arrayItemScalarFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate nullable nested array with nullable option 'itemsAndList'\", async () => {\n    const nullableNestedArrayField = sampleObjectType.fields.find(\n      field => field.name === \"nestedArrayWithNullableItemField\",\n    )!;\n    const arrayFieldType = nullableNestedArrayField.type as IntrospectionListTypeRef;\n    const arrayItemFieldType = arrayFieldType.ofType as IntrospectionListTypeRef;\n    const arrayItemScalarFieldType = arrayItemFieldType.ofType as IntrospectionNamedTypeRef;\n\n    expect(arrayFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemFieldType.kind).toEqual(TypeKind.LIST);\n    expect(arrayItemScalarFieldType.kind).toEqual(TypeKind.SCALAR);\n    expect(arrayItemScalarFieldType.name).toEqual(\"String\");\n  });\n\n  it(\"should generate not a list type for explicit scalar even when the reflected type is array\", async () => {\n    const overwrittenArrayScalarField = sampleObjectType.fields.find(\n      field => field.name === \"overwrittenArrayScalarField\",\n    )!;\n    const overwrittenArrayScalarFieldType =\n      overwrittenArrayScalarField.type as IntrospectionNonNullTypeRef;\n    const overwrittenArrayScalarFieldInnerType =\n      overwrittenArrayScalarFieldType.ofType as IntrospectionScalarType;\n\n    expect(overwrittenArrayScalarFieldType.kind).toEqual(TypeKind.NON_NULL);\n    expect(overwrittenArrayScalarFieldInnerType.kind).toEqual(TypeKind.SCALAR);\n    expect(overwrittenArrayScalarFieldInnerType.name).toEqual(\"DateTimeISO\");\n  });\n});\n"
  },
  {
    "path": "tests/functional/generic-types.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionInputObjectType,\n  type IntrospectionInterfaceType,\n  type IntrospectionListTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionScalarType,\n  type IntrospectionSchema,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport {\n  Arg,\n  type ClassType,\n  Field,\n  InputType,\n  Int,\n  InterfaceType,\n  ObjectType,\n  Query,\n  Resolver,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Generic types\", () => {\n  beforeEach(() => {\n    getMetadataStorage().clear();\n  });\n\n  it(\"shouldn't emit unused abstract object type\", async () => {\n    @ObjectType()\n    abstract class BaseType {\n      @Field()\n      baseField!: string;\n    }\n\n    @ObjectType()\n    class SampleType extends BaseType {\n      @Field()\n      sampleField!: string;\n    }\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(): SampleType {\n        return {\n          sampleField: \"sampleField\",\n          baseField: \"baseField\",\n        };\n      }\n    }\n\n    const { schemaIntrospection } = await getSchemaInfo({ resolvers: [SampleResolver] });\n\n    const sampleTypeInfo = schemaIntrospection.types.find(\n      it => it.name === \"SampleType\",\n    ) as IntrospectionObjectType;\n    const baseTypeInfo = schemaIntrospection.types.find(it => it.name === \"BaseType\") as undefined;\n\n    expect(sampleTypeInfo.fields).toHaveLength(2);\n    expect(baseTypeInfo).toBeUndefined();\n  });\n\n  it(\"shouldn't emit unused abstract interface type\", async () => {\n    @InterfaceType()\n    abstract class BaseInterfaceType {\n      @Field()\n      baseField!: string;\n    }\n\n    @InterfaceType()\n    abstract class SampleInterfaceType extends BaseInterfaceType {\n      @Field()\n      sampleField!: string;\n    }\n\n    @ObjectType({ implements: SampleInterfaceType })\n    class SampleType implements SampleInterfaceType {\n      @Field()\n      baseField!: string;\n\n      @Field()\n      sampleField!: string;\n    }\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(): SampleInterfaceType {\n        const sample = new SampleType();\n        sample.baseField = \"baseField\";\n        sample.sampleField = \"sampleField\";\n        return sample;\n      }\n    }\n\n    const { schemaIntrospection } = await getSchemaInfo({ resolvers: [SampleResolver] });\n\n    const sampleInterfaceTypeInfo = schemaIntrospection.types.find(\n      it => it.name === \"SampleInterfaceType\",\n    ) as IntrospectionInterfaceType;\n    const baseInterfaceTypeInfo = schemaIntrospection.types.find(\n      it => it.name === \"BaseInterfaceType\",\n    ) as undefined;\n\n    expect(sampleInterfaceTypeInfo.fields).toHaveLength(2);\n    expect(baseInterfaceTypeInfo).toBeUndefined();\n  });\n\n  it(\"shouldn't emit unused abstract input object type\", async () => {\n    @InputType()\n    abstract class BaseInput {\n      @Field()\n      baseField!: string;\n    }\n\n    @InputType()\n    class SampleInput extends BaseInput {\n      @Field()\n      sampleField!: string;\n    }\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(@Arg(\"input\") _input: SampleInput): boolean {\n        return true;\n      }\n    }\n\n    const { schemaIntrospection } = await getSchemaInfo({ resolvers: [SampleResolver] });\n\n    const sampleInputInfo = schemaIntrospection.types.find(\n      it => it.name === \"SampleInput\",\n    ) as IntrospectionInputObjectType;\n    const baseInputInfo = schemaIntrospection.types.find(\n      it => it.name === \"BaseInput\",\n    ) as undefined;\n\n    expect(sampleInputInfo.inputFields).toHaveLength(2);\n    expect(baseInputInfo).toBeUndefined();\n  });\n\n  describe(\"multiple children of base generic class\", () => {\n    let schema: GraphQLSchema;\n    let schemaIntrospection: IntrospectionSchema;\n    let dogsResponseMock: any;\n\n    beforeEach(async () => {\n      function Connection<TItem extends object>(TItemClass: ClassType<TItem>) {\n        @ObjectType(`${TItemClass.name}Connection`)\n        class ConnectionClass {\n          @Field(() => Int)\n          count!: number;\n\n          @Field(() => [TItemClass])\n          items!: TItem[];\n        }\n        return ConnectionClass;\n      }\n\n      @ObjectType()\n      class User {\n        @Field()\n        name!: string;\n      }\n\n      @ObjectType()\n      class Dog {\n        @Field()\n        canBark!: boolean;\n      }\n\n      const UserConnection = Connection(User);\n      // eslint-disable-next-line @typescript-eslint/no-redeclare\n      type UserConnection = InstanceType<typeof UserConnection>;\n      @ObjectType()\n      class DogConnection extends Connection(Dog) {}\n\n      dogsResponseMock = {\n        count: 2,\n        items: [{ canBark: false }, { canBark: true }],\n      } as DogConnection;\n\n      @Resolver()\n      class GenericConnectionResolver {\n        @Query(() => UserConnection)\n        users(): UserConnection {\n          return {\n            count: 2,\n            items: [{ name: \"Tony\" }, { name: \"Michael\" }],\n          };\n        }\n\n        @Query(() => DogConnection)\n        dogs(): DogConnection {\n          return dogsResponseMock;\n        }\n      }\n\n      ({ schema, schemaIntrospection } = await getSchemaInfo({\n        resolvers: [GenericConnectionResolver],\n      }));\n    });\n\n    it(\"should register proper types in schema using const and class syntax\", async () => {\n      const schemaObjectTypes = schemaIntrospection.types.filter(\n        it => it.kind === TypeKind.OBJECT && !it.name.startsWith(\"__\"),\n      );\n      const userConnectionTypeInfo = schemaObjectTypes.find(\n        it => it.name === \"UserConnection\",\n      ) as IntrospectionObjectType;\n      const userConnectionCountField = userConnectionTypeInfo.fields.find(\n        it => it.name === \"count\",\n      )!;\n      const userConnectionCountFieldType = (\n        userConnectionCountField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionScalarType;\n      const userConnectionItemsField = userConnectionTypeInfo.fields.find(\n        it => it.name === \"items\",\n      )!;\n      const userConnectionItemsFieldType = (\n        (\n          (userConnectionItemsField.type as IntrospectionNonNullTypeRef)\n            .ofType as IntrospectionListTypeRef\n        ).ofType as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionObjectType;\n\n      expect(schemaObjectTypes).toHaveLength(5); // Query, User, Dog, UserCon, DogCon\n      expect(userConnectionTypeInfo.fields).toHaveLength(2);\n      expect(userConnectionCountFieldType.kind).toBe(TypeKind.SCALAR);\n      expect(userConnectionCountFieldType.name).toBe(\"Int\");\n      expect(userConnectionItemsFieldType.kind).toBe(TypeKind.OBJECT);\n      expect(userConnectionItemsFieldType.name).toBe(\"User\");\n    });\n\n    it(\"should return child class data from query\", async () => {\n      const query = /* graphql */ `\n        query {\n          dogs {\n            count\n            items {\n              canBark\n            }\n          }\n        }\n      `;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data!.dogs).toEqual(dogsResponseMock);\n    });\n  });\n\n  describe(\"adding new properties in child class\", () => {\n    let schema: GraphQLSchema;\n    let schemaIntrospection: IntrospectionSchema;\n    let recipeEdgeResponse: any;\n    let friendshipEdgeResponse: any;\n\n    beforeEach(async () => {\n      function Edge<TNode extends object>(TNodeClass: ClassType<TNode>) {\n        @ObjectType()\n        abstract class EdgeClass {\n          @Field(() => TNodeClass)\n          node!: TNode;\n\n          @Field()\n          cursor!: string;\n        }\n        return EdgeClass;\n      }\n\n      @ObjectType()\n      class Recipe {\n        @Field()\n        title!: string;\n      }\n\n      @ObjectType()\n      class User {\n        @Field()\n        name!: string;\n      }\n\n      @ObjectType()\n      class RecipeEdge extends Edge(Recipe) {\n        @Field()\n        personalNotes!: string;\n      }\n      recipeEdgeResponse = {\n        cursor: \"recipeCursor\",\n        node: {\n          title: \"recipeTitle\",\n        },\n        personalNotes: \"recipePersonalNotes\",\n      } as RecipeEdge;\n\n      @ObjectType()\n      class FriendshipEdge extends Edge(User) {\n        @Field()\n        friendedAt!: Date;\n      }\n      friendshipEdgeResponse = {\n        cursor: \"friendshipCursor\",\n        node: {\n          name: \"userName\",\n        },\n        friendedAt: new Date(),\n      } as FriendshipEdge;\n\n      @Resolver()\n      class EdgeResolver {\n        @Query()\n        recipeEdge(): RecipeEdge {\n          return recipeEdgeResponse;\n        }\n\n        @Query()\n        friendshipEdge(): FriendshipEdge {\n          return friendshipEdgeResponse;\n        }\n      }\n\n      ({ schema, schemaIntrospection } = await getSchemaInfo({\n        resolvers: [EdgeResolver],\n      }));\n    });\n\n    it(\"should register fields properly in schema\", async () => {\n      const schemaObjectTypes = schemaIntrospection.types.filter(\n        it => it.kind === TypeKind.OBJECT && !it.name.startsWith(\"__\"),\n      );\n      const recipeEdgeTypeInfo = schemaObjectTypes.find(\n        it => it.name === \"RecipeEdge\",\n      ) as IntrospectionObjectType;\n      const recipeEdgeNodeField = recipeEdgeTypeInfo.fields.find(it => it.name === \"node\")!;\n      const recipeEdgeNodeFieldType = (recipeEdgeNodeField.type as IntrospectionNonNullTypeRef)\n        .ofType as IntrospectionObjectType;\n      const recipeEdgePersonalNotesField = recipeEdgeTypeInfo.fields.find(\n        it => it.name === \"personalNotes\",\n      )!;\n      const recipeEdgePersonalNotesFieldType = (\n        recipeEdgePersonalNotesField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionObjectType;\n      const friendshipEdgeTypeInfo = schemaObjectTypes.find(\n        it => it.name === \"FriendshipEdge\",\n      ) as IntrospectionObjectType;\n      const friendshipEdgeNodeField = friendshipEdgeTypeInfo.fields.find(it => it.name === \"node\")!;\n      const friendshipEdgeNodeFieldType = (\n        friendshipEdgeNodeField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionObjectType;\n      const friendshipEdgeFriendedAtField = friendshipEdgeTypeInfo.fields.find(\n        it => it.name === \"friendedAt\",\n      )!;\n      const friendshipEdgeFriendedAtFieldType = (\n        friendshipEdgeFriendedAtField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionObjectType;\n\n      expect(schemaObjectTypes).toHaveLength(5); // Query, User, Dog, UserCon, DogCon\n      expect(recipeEdgeTypeInfo.fields).toHaveLength(3);\n      expect(recipeEdgeNodeFieldType.kind).toBe(TypeKind.OBJECT);\n      expect(recipeEdgeNodeFieldType.name).toBe(\"Recipe\");\n      expect(recipeEdgePersonalNotesFieldType.kind).toBe(TypeKind.SCALAR);\n      expect(recipeEdgePersonalNotesFieldType.name).toBe(\"String\");\n      expect(friendshipEdgeTypeInfo.fields).toHaveLength(3);\n      expect(friendshipEdgeNodeFieldType.kind).toBe(TypeKind.OBJECT);\n      expect(friendshipEdgeNodeFieldType.name).toBe(\"User\");\n      expect(friendshipEdgeFriendedAtFieldType.kind).toBe(TypeKind.SCALAR);\n      expect(friendshipEdgeFriendedAtFieldType.name).toBe(\"DateTimeISO\");\n    });\n\n    it(\"should return child classes data from queries\", async () => {\n      const query = /* graphql */ `\n        query {\n          recipeEdge {\n            cursor\n            node {\n              title\n            }\n            personalNotes\n          }\n          friendshipEdge {\n            cursor\n            node {\n              name\n            }\n            friendedAt\n          }\n        }\n      `;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data!.recipeEdge).toEqual(recipeEdgeResponse);\n      expect(result.data!.friendshipEdge).toEqual({\n        ...friendshipEdgeResponse,\n        friendedAt: friendshipEdgeResponse.friendedAt.toISOString(),\n      });\n    });\n  });\n\n  describe(\"overwriting a property from base generic class in child class\", () => {\n    let schema: GraphQLSchema;\n    let schemaIntrospection: IntrospectionSchema;\n\n    beforeEach(async () => {\n      function Base<TType extends object>(TTypeClass: ClassType<TType>) {\n        @ObjectType()\n        class BaseClass {\n          @Field(() => TTypeClass)\n          baseField!: TType;\n        }\n        return BaseClass;\n      }\n\n      @ObjectType()\n      class BaseSample {\n        @Field()\n        sampleField!: string;\n      }\n\n      @ObjectType()\n      class ChildSample {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        childField!: string;\n      }\n\n      @ObjectType()\n      class Child extends Base(BaseSample) {\n        @Field()\n        override baseField!: ChildSample; // Overwriting field with a up compatible type\n      }\n\n      @Resolver()\n      class OverwriteResolver {\n        @Query()\n        child(): Child {\n          return {\n            baseField: {\n              sampleField: \"sampleField\",\n              childField: \"childField\",\n            },\n          };\n        }\n      }\n\n      ({ schema, schemaIntrospection } = await getSchemaInfo({\n        resolvers: [OverwriteResolver],\n      }));\n    });\n\n    it(\"should register proper type with overwritten field from base generic class\", async () => {\n      const childTypeInfo = schemaIntrospection.types.find(\n        it => it.name === \"Child\",\n      ) as IntrospectionObjectType;\n      const childTypeBaseField = childTypeInfo.fields.find(it => it.name === \"baseField\")!;\n      const childTypeBaseFieldType = (childTypeBaseField.type as IntrospectionNonNullTypeRef)\n        .ofType as IntrospectionObjectType;\n\n      expect(childTypeBaseFieldType.kind).toEqual(TypeKind.OBJECT);\n      expect(childTypeBaseFieldType.name).toEqual(\"ChildSample\");\n    });\n\n    it(\"should return overwritten child class data from query\", async () => {\n      const document = /* graphql */ `\n        query {\n          child {\n            baseField {\n              sampleField\n              childField\n            }\n          }\n        }\n      `;\n\n      const result: any = await graphql({ schema, source: document });\n\n      expect(result.data!).toEqual({\n        child: {\n          baseField: {\n            sampleField: \"sampleField\",\n            childField: \"childField\",\n          },\n        },\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/inputtype-enumerable-properties.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, graphql } from \"graphql\";\nimport { Arg, Field, InputType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"InputType enumerable properties\", () => {\n  let schema: GraphQLSchema;\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    @InputType()\n    class SampleInput {\n      @Field()\n      requiredField!: string;\n\n      @Field({ nullable: true })\n      optionalField?: string;\n\n      @Field({ nullable: true })\n      anotherOptional?: number;\n    }\n\n    @InputType()\n    class NestedInput {\n      @Field({ nullable: true })\n      optionalNested?: string;\n    }\n\n    @InputType()\n    class ParentInput {\n      @Field()\n      required!: string;\n\n      @Field(() => NestedInput, { nullable: true })\n      nested?: NestedInput;\n    }\n\n    @Resolver()\n    class SampleResolver {\n      @Query(() => String)\n      testSimpleInput(@Arg(\"input\") input: SampleInput): string {\n        return JSON.stringify({\n          keys: Object.keys(input),\n          hasOptional: \"optionalField\" in input,\n          hasAnother: \"anotherOptional\" in input,\n          optionalValue: input.optionalField,\n        });\n      }\n\n      @Query(() => String)\n      testNestedInput(@Arg(\"input\") input: ParentInput): string {\n        return JSON.stringify({\n          keys: Object.keys(input),\n          hasNested: \"nested\" in input,\n        });\n      }\n    }\n\n    schema = await buildSchema({\n      resolvers: [SampleResolver],\n      validate: false,\n    });\n  });\n\n  describe(\"optional fields not provided\", () => {\n    it(\"should not create enumerable properties for undefined optional fields\", async () => {\n      const query = `\n        query {\n          testSimpleInput(input: { requiredField: \"test\" })\n        }\n      `;\n\n      const result = await graphql({ schema, source: query });\n\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toBeDefined();\n\n      const data = JSON.parse(result.data!.testSimpleInput as string);\n\n      // Only requiredField should be in Object.keys()\n      expect(data.keys).toEqual([\"requiredField\"]);\n\n      // Optional fields should not be enumerable\n      expect(data.hasOptional).toBe(false);\n      expect(data.hasAnother).toBe(false);\n\n      // But should still be accessible (undefined)\n      expect(data.optionalValue).toBeUndefined();\n    });\n\n    it(\"should handle nested InputTypes correctly\", async () => {\n      const query = `\n        query {\n          testNestedInput(input: { required: \"value\" })\n        }\n      `;\n\n      const result = await graphql({ schema, source: query });\n\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toBeDefined();\n\n      const data = JSON.parse(result.data!.testNestedInput as string);\n\n      // Only required field should be enumerable\n      expect(data.keys).toEqual([\"required\"]);\n\n      // Nested optional field should not be enumerable\n      expect(data.hasNested).toBe(false);\n    });\n  });\n\n  describe(\"optional fields provided\", () => {\n    it(\"should include provided optional fields in Object.keys()\", async () => {\n      const query = `\n        query {\n          testSimpleInput(input: { requiredField: \"test\", optionalField: \"provided\" })\n        }\n      `;\n\n      const result = await graphql({ schema, source: query });\n\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toBeDefined();\n\n      const data = JSON.parse(result.data!.testSimpleInput as string);\n\n      // Both provided fields should be in Object.keys()\n      expect(data.keys).toContain(\"requiredField\");\n      expect(data.keys).toContain(\"optionalField\");\n\n      // Provided field should be enumerable\n      expect(data.hasOptional).toBe(true);\n\n      // Non-provided field should not be enumerable\n      expect(data.hasAnother).toBe(false);\n\n      // Value should be set\n      expect(data.optionalValue).toBe(\"provided\");\n    });\n\n    it(\"should handle explicitly null values correctly\", async () => {\n      const query = `\n        query {\n          testSimpleInput(input: { requiredField: \"test\", optionalField: null })\n        }\n      `;\n\n      const result = await graphql({ schema, source: query });\n\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toBeDefined();\n\n      const data = JSON.parse(result.data!.testSimpleInput as string);\n\n      // Explicitly null field should be in Object.keys()\n      expect(data.keys).toContain(\"requiredField\");\n      expect(data.keys).toContain(\"optionalField\");\n\n      // Should be enumerable\n      expect(data.hasOptional).toBe(true);\n\n      // Value should be null (not undefined)\n      expect(data.optionalValue).toBeNull();\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/interface-resolvers-args.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionInterfaceType,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionSchema,\n  graphql,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  Field,\n  FieldResolver,\n  Int,\n  InterfaceType,\n  ObjectType,\n  Query,\n  Resolver,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Interfaces with resolvers and arguments\", () => {\n  describe(\"Schema\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ArgsType()\n      class SampleArgs1 {\n        @Field(_type => Int)\n        classArg1!: number;\n\n        @Field(_type => Int)\n        classArg2!: number;\n      }\n\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgsFields {\n        @Field()\n        interfaceFieldInlineArgs(\n          @Arg(\"inlineArg1\", _type => Int) _inlineArg1: number,\n          @Arg(\"inlineArg2\", _type => Int) _inlineArg2: number,\n        ): string {\n          throw new Error(\"Method not implemented!\");\n        }\n\n        @Field()\n        interfaceFieldArgsType(@Args() _args: SampleArgs1): string {\n          throw new Error(\"Method not implemented!\");\n        }\n      }\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgs {\n        @Field()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") _sampleArg: string): string {\n          throw new Error(\"Method not implemented!\");\n        }\n      }\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgsAndInlineResolver {\n        @Field()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") sampleArg: string): string {\n          return `SampleInterfaceWithArgsAndInlineResolver: ${sampleArg}`;\n        }\n      }\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgsAndFieldResolver {}\n\n      @ObjectType({ implements: SampleInterfaceWithArgs })\n      class SampleImplementingObjectWithArgsAndOwnResolver implements SampleInterfaceWithArgs {\n        sampleFieldWithArgs(sampleArg: string) {\n          return `SampleImplementingObjectWithArgsAndOwnResolver: ${sampleArg}`;\n        }\n      }\n      @ObjectType({ implements: SampleInterfaceWithArgsAndInlineResolver })\n      class SampleImplementingObjectWithArgsAndInheritedResolver extends SampleInterfaceWithArgsAndInlineResolver {}\n      @ObjectType({ implements: SampleInterfaceWithArgsAndFieldResolver })\n      class SampleImplementingObjectWithArgsAndInheritedFieldResolver extends SampleInterfaceWithArgsAndFieldResolver {}\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): string {\n          return \"sampleQuery\";\n        }\n      }\n      @Resolver(_of => SampleInterfaceWithArgsAndFieldResolver)\n      class SampleInterfaceWithArgsResolver {\n        @FieldResolver()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") sampleArg: string): string {\n          return `SampleInterfaceWithArgsAndFieldResolver: ${sampleArg}`;\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver, SampleInterfaceWithArgsResolver],\n        orphanedTypes: [\n          SampleInterfaceWithArgsFields,\n          SampleInterfaceWithArgs,\n          SampleInterfaceWithArgsAndInlineResolver,\n          SampleInterfaceWithArgsAndFieldResolver,\n          SampleImplementingObjectWithArgsAndOwnResolver,\n          SampleImplementingObjectWithArgsAndInheritedResolver,\n          SampleImplementingObjectWithArgsAndInheritedFieldResolver,\n        ],\n      });\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n    });\n\n    it(\"should generate schema without errors\", async () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    it(\"should generate interface types fields with args correctly\", async () => {\n      const sampleInterfaceWithArgs = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceWithArgs\",\n      ) as IntrospectionInterfaceType;\n      const sampleInterfaceWithArgsAndInlineResolver = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceWithArgsAndInlineResolver\",\n      ) as IntrospectionInterfaceType;\n      const sampleInterfaceWithArgsAndFieldResolver = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceWithArgsAndFieldResolver\",\n      ) as IntrospectionInterfaceType;\n      expect(sampleInterfaceWithArgs).toBeDefined();\n      expect(sampleInterfaceWithArgsAndInlineResolver).toBeDefined();\n      expect(sampleInterfaceWithArgsAndFieldResolver).toBeDefined();\n\n      [\n        sampleInterfaceWithArgs,\n        sampleInterfaceWithArgsAndInlineResolver,\n        sampleInterfaceWithArgsAndFieldResolver,\n      ].forEach(type => {\n        const sampleFieldWithArgsField = type.fields.find(it => it.name === \"sampleFieldWithArgs\")!;\n        const sampleFieldWithArgsType = (\n          sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef\n        ).ofType as IntrospectionNamedTypeRef;\n\n        expect(sampleFieldWithArgsField.args).toHaveLength(1);\n        expect(sampleFieldWithArgsType.name).toEqual(\"String\");\n      });\n    });\n\n    it(\"should generate interface types fields with args both for inline and args class\", async () => {\n      const sampleInterfaceWithArgsFields = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceWithArgsFields\",\n      ) as IntrospectionInterfaceType;\n      expect(sampleInterfaceWithArgsFields).toBeDefined();\n\n      const interfaceFieldInlineArgsField = sampleInterfaceWithArgsFields.fields.find(\n        it => it.name === \"interfaceFieldInlineArgs\",\n      )!;\n      const interfaceFieldArgsTypeField = sampleInterfaceWithArgsFields.fields.find(\n        it => it.name === \"interfaceFieldArgsType\",\n      )!;\n      const interfaceFieldInlineArgsType = (\n        interfaceFieldInlineArgsField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionNamedTypeRef;\n      const interfaceFieldArgsTypeFieldType = (\n        interfaceFieldArgsTypeField.type as IntrospectionNonNullTypeRef\n      ).ofType as IntrospectionNamedTypeRef;\n\n      expect(interfaceFieldInlineArgsField.args).toHaveLength(2);\n      expect(interfaceFieldArgsTypeField.args).toHaveLength(2);\n      expect(interfaceFieldInlineArgsType.name).toEqual(\"String\");\n      expect(interfaceFieldArgsTypeFieldType.name).toEqual(\"String\");\n    });\n\n    it(\"should generate object types inherited interface fields with args correctly\", async () => {\n      const sampleImplementingObjectWithArgsAndOwnResolver = schemaIntrospection.types.find(\n        type => type.name === \"SampleImplementingObjectWithArgsAndOwnResolver\",\n      ) as IntrospectionInterfaceType;\n      const sampleImplementingObjectWithArgsAndInheritedResolver = schemaIntrospection.types.find(\n        type => type.name === \"SampleImplementingObjectWithArgsAndInheritedResolver\",\n      ) as IntrospectionInterfaceType;\n      const sampleImplementingObjectWithArgsAndInheritedFieldResolver =\n        schemaIntrospection.types.find(\n          type => type.name === \"SampleImplementingObjectWithArgsAndInheritedFieldResolver\",\n        ) as IntrospectionInterfaceType;\n      expect(sampleImplementingObjectWithArgsAndOwnResolver).toBeDefined();\n      expect(sampleImplementingObjectWithArgsAndInheritedResolver).toBeDefined();\n      expect(sampleImplementingObjectWithArgsAndInheritedFieldResolver).toBeDefined();\n\n      [\n        sampleImplementingObjectWithArgsAndOwnResolver,\n        sampleImplementingObjectWithArgsAndInheritedResolver,\n        sampleImplementingObjectWithArgsAndInheritedFieldResolver,\n      ].forEach(type => {\n        const sampleFieldWithArgsField = type.fields.find(it => it.name === \"sampleFieldWithArgs\")!;\n        const sampleFieldWithArgsType = (\n          sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef\n        ).ofType as IntrospectionNamedTypeRef;\n\n        expect(sampleFieldWithArgsField.args).toHaveLength(1);\n        expect(sampleFieldWithArgsType.name).toEqual(\"String\");\n      });\n    });\n  });\n\n  describe(\"Functional\", () => {\n    let schema: GraphQLSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgs {\n        @Field()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") _sampleArg: string): string {\n          throw new Error(\"Method not implemented!\");\n        }\n      }\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgsAndInlineResolver {\n        @Field()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") sampleArg: string): string {\n          return `SampleInterfaceWithArgsAndInlineResolver: ${sampleArg}`;\n        }\n      }\n      @InterfaceType({ implements: SampleInterfaceWithArgsAndInlineResolver })\n      abstract class SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver extends SampleInterfaceWithArgsAndInlineResolver {}\n      @InterfaceType()\n      abstract class SampleInterfaceWithArgsAndFieldResolver {}\n\n      @ObjectType({ implements: SampleInterfaceWithArgs })\n      class SampleImplementingObjectWithArgsAndOwnResolver extends SampleInterfaceWithArgs {\n        override sampleFieldWithArgs(sampleArg: string) {\n          return `SampleImplementingObjectWithArgsAndOwnResolver: ${sampleArg}`;\n        }\n      }\n      @ObjectType({ implements: SampleInterfaceWithArgsAndInlineResolver })\n      class SampleImplementingObjectWithArgsAndInheritedResolver extends SampleInterfaceWithArgsAndInlineResolver {}\n      @ObjectType({\n        implements: [\n          SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver,\n          SampleInterfaceWithArgsAndInlineResolver,\n        ],\n      })\n      class SampleObjectImplementingInterfaceImplementingWithArgsAndInheritedResolver\n        extends SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver\n        implements SampleInterfaceWithArgsAndInlineResolver {}\n      @ObjectType({ implements: SampleInterfaceWithArgsAndFieldResolver })\n      class SampleImplementingObjectWithArgsAndInheritedFieldResolver extends SampleInterfaceWithArgsAndFieldResolver {}\n\n      @Resolver(_of => SampleInterfaceWithArgsAndFieldResolver)\n      class SampleInterfaceResolver {\n        @FieldResolver()\n        sampleFieldWithArgs(@Arg(\"sampleArg\") sampleArg: string): string {\n          return `SampleInterfaceResolver: ${sampleArg}`;\n        }\n      }\n      @Resolver()\n      class TestResolver {\n        @Query()\n        queryForSampleInterfaceWithArgs(): SampleInterfaceWithArgs {\n          return new SampleImplementingObjectWithArgsAndOwnResolver();\n        }\n\n        @Query()\n        queryForSampleInterfaceWithArgsAndInlineResolver(): SampleInterfaceWithArgsAndInlineResolver {\n          return new SampleImplementingObjectWithArgsAndInheritedResolver();\n        }\n\n        @Query()\n        queryForSampleInterfaceWithArgsAndFieldResolver(): SampleInterfaceWithArgsAndFieldResolver {\n          return new SampleImplementingObjectWithArgsAndInheritedFieldResolver();\n        }\n\n        @Query()\n        queryForSampleImplementingObjectWithArgsAndOwnResolver(): SampleImplementingObjectWithArgsAndOwnResolver {\n          return new SampleImplementingObjectWithArgsAndOwnResolver();\n        }\n\n        @Query()\n        queryForSampleImplementingObjectWithArgsAndInheritedResolver(): SampleImplementingObjectWithArgsAndInheritedResolver {\n          return new SampleImplementingObjectWithArgsAndInheritedResolver();\n        }\n\n        @Query()\n        queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver(): SampleImplementingObjectWithArgsAndInheritedFieldResolver {\n          return new SampleImplementingObjectWithArgsAndInheritedFieldResolver();\n        }\n\n        @Query()\n        queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver(): SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver {\n          return new SampleObjectImplementingInterfaceImplementingWithArgsAndInheritedResolver();\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleInterfaceResolver, TestResolver],\n        orphanedTypes: [\n          SampleInterfaceWithArgs,\n          SampleInterfaceWithArgsAndInlineResolver,\n          SampleInterfaceWithArgsAndFieldResolver,\n          SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver,\n          SampleImplementingObjectWithArgsAndOwnResolver,\n          SampleImplementingObjectWithArgsAndInheritedResolver,\n          SampleImplementingObjectWithArgsAndInheritedFieldResolver,\n          SampleObjectImplementingInterfaceImplementingWithArgsAndInheritedResolver,\n        ],\n        validate: false,\n      });\n    });\n\n    it(\"should build the schema without errors\", () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should invoke object type field resolver for interface returned query if override the interface type one\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleInterfaceWithArgs {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleInterfaceWithArgs.sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleImplementingObjectWithArgsAndOwnResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke interface type inline field resolver for interface returned query\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleInterfaceWithArgsAndInlineResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleInterfaceWithArgsAndInlineResolver\n        .sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleInterfaceWithArgsAndInlineResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke interface type resolvers field resolver for interface returned query\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleInterfaceWithArgsAndFieldResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleInterfaceWithArgsAndFieldResolver\n        .sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleInterfaceResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke object type field resolver if override the interface type one\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleImplementingObjectWithArgsAndOwnResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleImplementingObjectWithArgsAndOwnResolver\n        .sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleImplementingObjectWithArgsAndOwnResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke interface type inline field resolver for implementing object type\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleImplementingObjectWithArgsAndInheritedResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleImplementingObjectWithArgsAndInheritedResolver\n        .sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleInterfaceWithArgsAndInlineResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke interface type resolvers field resolver for implementing object type\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any).queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver\n        .sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleInterfaceResolver: sampleArgValue\");\n    });\n\n    it(\"should invoke interface type resolvers field resolver from implemented interface for implementing object type\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver {\n            sampleFieldWithArgs(sampleArg: \"sampleArgValue\")\n          }\n        }\n      `;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      const result = (data as any)\n        .queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver.sampleFieldWithArgs;\n      expect(result).toBeDefined();\n      expect(result).toEqual(\"SampleInterfaceWithArgsAndInlineResolver: sampleArgValue\");\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/interfaces-and-inheritance.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionInputObjectType,\n  type IntrospectionInterfaceType,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  Field,\n  ID,\n  InputType,\n  Int,\n  InterfaceType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  buildSchema,\n} from \"type-graphql\";\nimport { GeneratingSchemaError } from \"@/errors\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\nimport { getInnerFieldType, getInnerInputFieldType } from \"../helpers/getInnerFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Interfaces and inheritance\", () => {\n  describe(\"Schema\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n    let queryType: IntrospectionObjectType;\n    let sampleInterface1Type: IntrospectionInterfaceType;\n    let sampleInterface2Type: IntrospectionInterfaceType;\n    let sampleInterfaceImplementing1: IntrospectionInterfaceType;\n    let sampleMultiImplementingObjectType: IntrospectionObjectType;\n    let sampleExtendingImplementingObjectType: IntrospectionObjectType;\n    let sampleImplementingObject1Type: IntrospectionObjectType;\n    let sampleImplementingObject2Type: IntrospectionObjectType;\n    let sampleExtendingObject2Type: IntrospectionObjectType;\n    let sampleSecondExtendedInputType: IntrospectionInputObjectType;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @InterfaceType()\n      abstract class SampleInterface1 {\n        @Field(() => ID)\n        id!: string;\n\n        @Field()\n        interfaceStringField1!: string;\n      }\n      @InterfaceType()\n      abstract class SampleInterface2 {\n        @Field(() => ID)\n        id!: string;\n\n        @Field()\n        interfaceStringField2!: string;\n      }\n      @InterfaceType()\n      abstract class SampleInterfaceExtending1 extends SampleInterface1 {\n        @Field()\n        ownStringField1!: string;\n      }\n      @InterfaceType({ implements: [SampleInterface1] })\n      abstract class SampleInterfaceImplementing1 implements SampleInterface1 {\n        id!: string;\n\n        interfaceStringField1!: string;\n\n        @Field()\n        ownStringField1!: string;\n      }\n\n      @ObjectType({ implements: SampleInterface1 })\n      class SampleImplementingObject1 implements SampleInterface1 {\n        id!: string;\n\n        interfaceStringField1!: string;\n\n        @Field()\n        ownField1!: number;\n      }\n      @ObjectType({ implements: SampleInterface1 })\n      class SampleImplementingObject2 implements SampleInterface1 {\n        @Field(() => ID)\n        id!: string;\n\n        @Field()\n        interfaceStringField1!: string;\n\n        @Field()\n        ownField2!: number;\n      }\n      @ObjectType({ implements: [SampleInterface1, SampleInterface2] })\n      class SampleMultiImplementingObject implements SampleInterface1, SampleInterface2 {\n        id!: string;\n\n        interfaceStringField1!: string;\n\n        interfaceStringField2!: string;\n\n        @Field()\n        ownField3!: number;\n      }\n      @ObjectType({ implements: SampleInterface1 })\n      class SampleExtendingImplementingObject\n        extends SampleImplementingObject2\n        implements SampleInterface1\n      {\n        @Field()\n        ownField4!: number;\n      }\n      @ObjectType()\n      class SampleExtendingObject2 extends SampleImplementingObject2 {\n        @Field()\n        ownExtendingField2!: number;\n      }\n\n      @ArgsType()\n      class SampleBaseArgs {\n        @Field()\n        baseArgField!: string;\n      }\n      @ArgsType()\n      class SampleExtendingArgs extends SampleBaseArgs {\n        @Field()\n        extendingArgField!: boolean;\n      }\n\n      @InputType()\n      class SampleBaseInput {\n        @Field()\n        baseInputField!: string;\n      }\n      @InputType()\n      class SampleExtendingInput extends SampleBaseInput {\n        @Field()\n        extendingInputField!: boolean;\n      }\n\n      // overwriting fields case\n      @InputType()\n      class SampleFirstBaseInput {\n        @Field()\n        baseField!: string;\n      }\n      @InputType()\n      class SampleFirstExtendedInput extends SampleFirstBaseInput {\n        @Field()\n        extendedField!: string;\n      }\n      @InputType()\n      class SampleSecondBaseInput {\n        @Field()\n        baseInputField!: SampleFirstBaseInput;\n      }\n      @InputType()\n      class SampleSecondExtendedInput extends SampleSecondBaseInput {\n        @Field()\n        override baseInputField!: SampleFirstExtendedInput;\n      }\n\n      class SampleResolver {\n        @Query()\n        sampleQuery(): boolean {\n          return true;\n        }\n\n        @Query()\n        queryWithArgs(@Args() _args: SampleExtendingArgs): boolean {\n          return true;\n        }\n\n        @Mutation()\n        mutationWithInput(@Arg(\"input\") _input: SampleExtendingInput): boolean {\n          return true;\n        }\n      }\n\n      // get builded schema info from retrospection\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        orphanedTypes: [\n          SampleInterface1,\n          SampleInterfaceExtending1,\n          SampleInterfaceImplementing1,\n          SampleImplementingObject1,\n          SampleImplementingObject2,\n          SampleMultiImplementingObject,\n          SampleExtendingImplementingObject,\n          SampleExtendingObject2,\n          SampleSecondExtendedInput,\n        ],\n      });\n      queryType = schemaInfo.queryType;\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      sampleInterface1Type = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterface1\",\n      ) as IntrospectionInterfaceType;\n      sampleInterface2Type = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterface2\",\n      ) as IntrospectionInterfaceType;\n      sampleInterfaceImplementing1 = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceImplementing1\",\n      ) as IntrospectionInterfaceType;\n      sampleImplementingObject1Type = schemaIntrospection.types.find(\n        type => type.name === \"SampleImplementingObject1\",\n      ) as IntrospectionObjectType;\n      sampleImplementingObject2Type = schemaIntrospection.types.find(\n        type => type.name === \"SampleImplementingObject2\",\n      ) as IntrospectionObjectType;\n      sampleExtendingImplementingObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleExtendingImplementingObject\",\n      ) as IntrospectionObjectType;\n      sampleMultiImplementingObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleMultiImplementingObject\",\n      ) as IntrospectionObjectType;\n      sampleExtendingObject2Type = schemaIntrospection.types.find(\n        type => type.name === \"SampleExtendingObject2\",\n      ) as IntrospectionObjectType;\n      sampleSecondExtendedInputType = schemaIntrospection.types.find(\n        type => type.name === \"SampleSecondExtendedInput\",\n      ) as IntrospectionInputObjectType;\n    });\n\n    // helpers\n    function getInnerType(fieldType: any) {\n      return (fieldType.type as IntrospectionNonNullTypeRef).ofType! as IntrospectionNamedTypeRef;\n    }\n\n    it(\"should generate schema without errors\", async () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    it(\"should generate interface type correctly\", async () => {\n      expect(sampleInterface1Type).toBeDefined();\n      expect(sampleInterface2Type).toBeDefined();\n      expect(sampleInterface1Type.kind).toEqual(TypeKind.INTERFACE);\n      expect(sampleInterface2Type.kind).toEqual(TypeKind.INTERFACE);\n      expect(sampleInterface1Type.fields).toHaveLength(2);\n      expect(sampleInterface2Type.fields).toHaveLength(2);\n\n      const idFieldType1 = getInnerFieldType(sampleInterface1Type, \"id\");\n      const idFieldType2 = getInnerFieldType(sampleInterface1Type, \"id\");\n      const interfaceStringField1 = getInnerFieldType(\n        sampleInterface1Type,\n        \"interfaceStringField1\",\n      );\n      const interfaceStringField2 = getInnerFieldType(\n        sampleInterface2Type,\n        \"interfaceStringField2\",\n      );\n\n      expect(idFieldType1.name).toEqual(\"ID\");\n      expect(idFieldType2.name).toEqual(\"ID\");\n      expect(interfaceStringField1.name).toEqual(\"String\");\n      expect(interfaceStringField2.name).toEqual(\"String\");\n    });\n\n    it(\"should generate type of interface extending other interface correctly\", async () => {\n      const sampleInterfaceExtending1 = schemaIntrospection.types.find(\n        type => type.name === \"SampleInterfaceExtending1\",\n      ) as IntrospectionInterfaceType;\n      expect(sampleInterfaceExtending1).toBeDefined();\n      expect(sampleInterfaceExtending1.kind).toEqual(TypeKind.INTERFACE);\n      expect(sampleInterfaceExtending1.fields).toHaveLength(3);\n\n      const idFieldType = getInnerFieldType(sampleInterfaceExtending1, \"id\");\n      const interfaceStringField = getInnerFieldType(\n        sampleInterfaceExtending1,\n        \"interfaceStringField1\",\n      );\n      const ownStringField1 = getInnerFieldType(sampleInterfaceExtending1, \"ownStringField1\");\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField.name).toEqual(\"String\");\n      expect(ownStringField1.name).toEqual(\"String\");\n    });\n\n    it(\"should generate type of interface implementing other interface correctly\", async () => {\n      expect(sampleInterfaceImplementing1).toBeDefined();\n      expect(sampleInterfaceImplementing1.kind).toEqual(TypeKind.INTERFACE);\n      expect(sampleInterfaceImplementing1.fields).toHaveLength(3);\n\n      expect(sampleInterfaceImplementing1.interfaces).toContainEqual(\n        expect.objectContaining({\n          name: \"SampleInterface1\",\n        }),\n      );\n\n      const idFieldType = getInnerFieldType(sampleInterfaceImplementing1, \"id\");\n      expect(idFieldType.name).toEqual(\"ID\");\n      const interfaceStringField = getInnerFieldType(\n        sampleInterfaceImplementing1,\n        \"interfaceStringField1\",\n      );\n      expect(interfaceStringField.name).toEqual(\"String\");\n      const ownStringField1 = getInnerFieldType(sampleInterfaceImplementing1, \"ownStringField1\");\n      expect(ownStringField1.name).toEqual(\"String\");\n    });\n\n    it(\"should generate object type explicitly implementing interface correctly\", async () => {\n      expect(sampleImplementingObject2Type).toBeDefined();\n      expect(sampleImplementingObject2Type.fields).toHaveLength(3);\n\n      const idFieldType = getInnerFieldType(sampleImplementingObject2Type, \"id\");\n      const interfaceStringField = getInnerFieldType(\n        sampleImplementingObject2Type,\n        \"interfaceStringField1\",\n      );\n      const ownField2 = getInnerFieldType(sampleImplementingObject2Type, \"ownField2\");\n      const implementedInterfaceInfo = sampleImplementingObject2Type.interfaces.find(\n        it => it.name === \"SampleInterface1\",\n      )!;\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField.name).toEqual(\"String\");\n      expect(ownField2.name).toEqual(\"Float\");\n      expect(implementedInterfaceInfo.kind).toEqual(TypeKind.INTERFACE);\n    });\n\n    it(\"should generate object type implicitly implementing interface correctly\", async () => {\n      expect(sampleImplementingObject1Type).toBeDefined();\n      expect(sampleImplementingObject1Type.fields).toHaveLength(3);\n\n      const idFieldType = getInnerFieldType(sampleImplementingObject1Type, \"id\");\n      const interfaceStringField1 = getInnerFieldType(\n        sampleImplementingObject1Type,\n        \"interfaceStringField1\",\n      );\n      const ownField1 = getInnerFieldType(sampleImplementingObject1Type, \"ownField1\");\n      const implementedInterfaceInfo = sampleImplementingObject2Type.interfaces.find(\n        it => it.name === \"SampleInterface1\",\n      )!;\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField1.name).toEqual(\"String\");\n      expect(ownField1.name).toEqual(\"Float\");\n      expect(implementedInterfaceInfo.kind).toEqual(TypeKind.INTERFACE);\n    });\n\n    it(\"should generate object type extending other object type correctly\", async () => {\n      expect(sampleExtendingObject2Type).toBeDefined();\n      expect(sampleExtendingObject2Type.fields).toHaveLength(4);\n\n      const idFieldType = getInnerFieldType(sampleExtendingObject2Type, \"id\");\n      const interfaceStringField1 = getInnerFieldType(\n        sampleExtendingObject2Type,\n        \"interfaceStringField1\",\n      );\n      const ownField2 = getInnerFieldType(sampleExtendingObject2Type, \"ownField2\");\n      const ownExtendingField2 = getInnerFieldType(\n        sampleExtendingObject2Type,\n        \"ownExtendingField2\",\n      );\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField1.name).toEqual(\"String\");\n      expect(ownField2.name).toEqual(\"Float\");\n      expect(ownExtendingField2.name).toEqual(\"Float\");\n    });\n\n    it(\"should generate object type implementing interface when extending object type\", async () => {\n      expect(sampleExtendingObject2Type).toBeDefined();\n\n      const implementedInterfaceInfo = sampleExtendingObject2Type.interfaces.find(\n        it => it.name === \"SampleInterface1\",\n      )!;\n\n      expect(implementedInterfaceInfo).toBeDefined();\n      expect(implementedInterfaceInfo.kind).toEqual(TypeKind.INTERFACE);\n    });\n\n    it(\"should generate object type implicitly implementing multiple interfaces correctly\", async () => {\n      expect(sampleMultiImplementingObjectType).toBeDefined();\n      expect(sampleMultiImplementingObjectType.fields).toHaveLength(4);\n\n      const idFieldType = getInnerFieldType(sampleMultiImplementingObjectType, \"id\");\n      const interfaceStringField1 = getInnerFieldType(\n        sampleMultiImplementingObjectType,\n        \"interfaceStringField1\",\n      );\n      const interfaceStringField2 = getInnerFieldType(\n        sampleMultiImplementingObjectType,\n        \"interfaceStringField2\",\n      );\n      const ownField3 = getInnerFieldType(sampleMultiImplementingObjectType, \"ownField3\");\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField1.name).toEqual(\"String\");\n      expect(interfaceStringField2.name).toEqual(\"String\");\n      expect(ownField3.name).toEqual(\"Float\");\n    });\n\n    it(\"should generate object type implicitly implementing and extending correctly\", async () => {\n      expect(sampleExtendingImplementingObjectType).toBeDefined();\n      expect(sampleExtendingImplementingObjectType.fields).toHaveLength(4);\n\n      const idFieldType = getInnerFieldType(sampleExtendingImplementingObjectType, \"id\");\n      const interfaceStringField1 = getInnerFieldType(\n        sampleExtendingImplementingObjectType,\n        \"interfaceStringField1\",\n      );\n      const ownField2 = getInnerFieldType(sampleExtendingImplementingObjectType, \"ownField2\");\n      const ownField4 = getInnerFieldType(sampleExtendingImplementingObjectType, \"ownField4\");\n\n      expect(idFieldType.name).toEqual(\"ID\");\n      expect(interfaceStringField1.name).toEqual(\"String\");\n      expect(ownField2.name).toEqual(\"Float\");\n      expect(ownField4.name).toEqual(\"Float\");\n    });\n\n    it(\"should generate query args when extending other args class\", async () => {\n      const queryWithArgs = queryType.fields.find(query => query.name === \"queryWithArgs\")!;\n      expect(queryWithArgs.args).toHaveLength(2);\n\n      const baseArgFieldType = getInnerType(\n        queryWithArgs.args.find(arg => arg.name === \"baseArgField\")!,\n      );\n      const extendingArgFieldType = getInnerType(\n        queryWithArgs.args.find(arg => arg.name === \"extendingArgField\")!,\n      );\n\n      expect(baseArgFieldType.name).toEqual(\"String\");\n      expect(extendingArgFieldType.name).toEqual(\"Boolean\");\n    });\n\n    it(\"should generate mutation input when extending other args class\", async () => {\n      const sampleExtendingInputType = schemaIntrospection.types.find(\n        type => type.name === \"SampleExtendingInput\",\n      ) as IntrospectionInputObjectType;\n      const baseInputFieldType = getInnerType(\n        sampleExtendingInputType.inputFields.find(field => field.name === \"baseInputField\")!,\n      );\n      const extendingInputFieldType = getInnerType(\n        sampleExtendingInputType.inputFields.find(field => field.name === \"extendingInputField\")!,\n      );\n\n      expect(baseInputFieldType.name).toEqual(\"String\");\n      expect(extendingInputFieldType.name).toEqual(\"Boolean\");\n    });\n\n    it(\"should properly overwrite input type field\", () => {\n      const baseInputFieldType = getInnerInputFieldType(\n        sampleSecondExtendedInputType,\n        \"baseInputField\",\n      );\n\n      expect(baseInputFieldType.name).toEqual(\"SampleFirstExtendedInput\");\n    });\n\n    it(\"shouldn't throw error when extending wrong class type\", async () => {\n      getMetadataStorage().clear();\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        inputField!: string;\n      }\n      @ArgsType()\n      class SampleArgs extends SampleInput {\n        @Field()\n        argField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args() _args: SampleArgs): boolean {\n          return true;\n        }\n      }\n      const schema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n      expect(schema).toBeDefined();\n    });\n  });\n\n  describe(\"Schema > deeply nested inheritance chain\", () => {\n    beforeEach(() => {\n      getMetadataStorage().clear();\n    });\n\n    it(\"should properly inherit overridden fields\", async () => {\n      @ArgsType()\n      class BaseArgs {\n        @Field({ nullable: true })\n        baseField?: string;\n      }\n\n      @ArgsType()\n      class FirstLevelArgs extends BaseArgs {\n        @Field({ nullable: false })\n        override baseField!: string;\n      }\n\n      @ArgsType()\n      class SecondLevelArgs extends FirstLevelArgs {\n        @Field()\n        secondLevelField!: string;\n      }\n\n      @Resolver()\n      class TestResolver {\n        @Query(() => Boolean)\n        testQuery(@Args() _args: SecondLevelArgs): boolean {\n          return true;\n        }\n      }\n\n      const { queryType } = await getSchemaInfo({\n        resolvers: [TestResolver],\n      });\n\n      const testQuery = queryType.fields.find(field => field.name === \"testQuery\")!;\n      const baseField = testQuery.args.find(arg => arg.name === \"baseField\")!;\n      expect(baseField.type).toMatchObject({\n        kind: \"NON_NULL\",\n        ofType: {\n          kind: \"SCALAR\",\n          name: \"String\",\n          ofType: null,\n        },\n      });\n    });\n  });\n\n  describe(\"Errors\", () => {\n    beforeEach(() => {\n      getMetadataStorage().clear();\n    });\n\n    it(\"should throw error when field type doesn't match with interface\", async () => {\n      const error = await expectToThrow(async () => {\n        @InterfaceType()\n        class IBase {\n          @Field()\n          baseField!: string;\n        }\n        @ObjectType({ implements: IBase })\n        class ChildObject implements IBase {\n          @Field(() => Number, { nullable: true })\n          baseField!: string;\n\n          @Field()\n          argField!: string;\n        }\n        class SampleResolver {\n          @Query()\n          sampleQuery(): ChildObject {\n            return {} as ChildObject;\n          }\n        }\n\n        await buildSchema({\n          resolvers: [SampleResolver],\n          validate: false,\n        });\n      });\n\n      expect(error).toBeInstanceOf(GeneratingSchemaError);\n      expect(error.message).toMatchInlineSnapshot(`\n          \"Some errors occurred while generating GraphQL schema:\n            Interface field IBase.baseField expects type String! but ChildObject.baseField is type Float.\n          Please check the \\`details\\` property of the error to get more detailed info.\"\n        `);\n      expect(JSON.stringify((error as GeneratingSchemaError).details, null, 2))\n        .toMatchInlineSnapshot(`\n          \"[\n            {\n              \"message\": \"Interface field IBase.baseField expects type String! but ChildObject.baseField is type Float.\"\n            }\n          ]\"\n        `);\n    });\n\n    it(\"should throw error when not interface type is provided as `implements` option\", async () => {\n      const error = await expectToThrow(async () => {\n        @ObjectType()\n        class SampleNotInterface {\n          @Field()\n          sampleField!: string;\n        }\n        @ObjectType({ implements: [SampleNotInterface] })\n        class SampleImplementingObject implements SampleNotInterface {\n          @Field()\n          sampleField!: string;\n        }\n        @Resolver()\n        class SampleResolver {\n          @Query()\n          sampleQuery(): SampleImplementingObject {\n            return {} as SampleImplementingObject;\n          }\n        }\n\n        await buildSchema({\n          resolvers: [SampleResolver],\n          validate: false,\n        });\n      });\n\n      expect(error).toBeInstanceOf(Error);\n      expect(error.message).toMatchInlineSnapshot(\n        `\"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.\"`,\n      );\n    });\n  });\n\n  describe(\"Functional\", () => {\n    let schema: GraphQLSchema;\n    let queryArgs: any;\n    let mutationInput: any;\n    let inputFieldValue: any;\n    let argsFieldValue: any;\n\n    beforeEach(() => {\n      queryArgs = undefined;\n      mutationInput = undefined;\n    });\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ArgsType()\n      class BaseArgs {\n        @Field()\n        baseArgField!: string;\n\n        @Field(() => Int, { nullable: true })\n        optionalBaseArgField: number = 255;\n      }\n      @ArgsType()\n      class ChildArgs extends BaseArgs {\n        @Field()\n        childArgField!: string;\n      }\n\n      @InputType()\n      class BaseInput {\n        @Field()\n        baseInputField!: string;\n\n        @Field(() => Int, { nullable: true })\n        optionalBaseInputField: number = 255;\n      }\n      @InputType()\n      class ChildInput extends BaseInput {\n        @Field()\n        childInputField!: string;\n      }\n\n      @InterfaceType()\n      abstract class BaseInterface {\n        @Field()\n        baseInterfaceField!: string;\n\n        @Field({ name: \"renamedInterfaceField\", nullable: true })\n        interfaceFieldToBeRenamed?: string;\n      }\n      @ObjectType({ implements: BaseInterface })\n      class FirstImplementation implements BaseInterface {\n        baseInterfaceField!: string;\n\n        interfaceFieldToBeRenamed?: string;\n\n        @Field()\n        firstField!: string;\n      }\n      @ObjectType({ implements: BaseInterface })\n      class SecondImplementation implements BaseInterface {\n        baseInterfaceField!: string;\n\n        @Field()\n        secondField!: string;\n      }\n\n      @InterfaceType({\n        resolveType: value => {\n          if (\"firstField\" in value) {\n            return \"FirstInterfaceWithStringResolveTypeObject\";\n          }\n          if (\"secondField\" in value) {\n            return \"SecondInterfaceWithStringResolveTypeObject\";\n          }\n          return undefined;\n        },\n      })\n      abstract class InterfaceWithStringResolveType {\n        @Field()\n        baseInterfaceField!: string;\n      }\n      @ObjectType({ implements: InterfaceWithStringResolveType })\n      class FirstInterfaceWithStringResolveTypeObject implements InterfaceWithStringResolveType {\n        baseInterfaceField!: string;\n\n        @Field()\n        firstField!: string;\n      }\n      @ObjectType({ implements: InterfaceWithStringResolveType })\n      class SecondInterfaceWithStringResolveTypeObject implements InterfaceWithStringResolveType {\n        baseInterfaceField!: string;\n\n        @Field()\n        secondField!: string;\n      }\n\n      @InterfaceType({\n        resolveType: value => {\n          if (\"firstField\" in value) {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            return FirstInterfaceWithClassResolveTypeObject;\n          }\n          if (\"secondField\" in value) {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            return SecondInterfaceWithClassResolveTypeObject;\n          }\n          return undefined;\n        },\n      })\n      abstract class InterfaceWithClassResolveType {\n        @Field()\n        baseInterfaceField!: string;\n      }\n      @ObjectType({ implements: InterfaceWithClassResolveType })\n      class FirstInterfaceWithClassResolveTypeObject implements InterfaceWithClassResolveType {\n        baseInterfaceField!: string;\n\n        @Field()\n        firstField!: string;\n      }\n      @ObjectType({ implements: InterfaceWithClassResolveType })\n      class SecondInterfaceWithClassResolveTypeObject implements InterfaceWithClassResolveType {\n        baseInterfaceField!: string;\n\n        @Field()\n        secondField!: string;\n      }\n\n      class SampleBaseClass {\n        static sampleStaticMethod() {\n          return \"sampleStaticMethod\";\n        }\n      }\n      @ObjectType()\n      class SampleExtendingNormalClassObject extends SampleBaseClass {\n        @Field()\n        sampleField!: string;\n      }\n      @InputType()\n      class SampleExtendingNormalClassInput extends SampleBaseClass {\n        @Field()\n        sampleField!: string;\n      }\n      @ArgsType()\n      class SampleExtendingNormalClassArgs extends SampleBaseClass {\n        @Field()\n        sampleField!: string;\n      }\n\n      // overwriting fields case\n      @InputType()\n      class SampleFirstBaseInput {\n        @Field()\n        baseField!: string;\n      }\n      @InputType()\n      class SampleFirstExtendedInput extends SampleFirstBaseInput {\n        @Field()\n        extendedField!: string;\n      }\n      @InputType()\n      class SampleSecondBaseInput {\n        @Field()\n        baseInputField!: SampleFirstBaseInput;\n      }\n      @InputType()\n      class SampleSecondExtendedInput extends SampleSecondBaseInput {\n        @Field()\n        override baseInputField!: SampleFirstExtendedInput;\n      }\n\n      @Resolver()\n      class InterfacesResolver {\n        @Query()\n        getInterfacePlainObject(): BaseInterface {\n          return {} as FirstImplementation;\n        }\n\n        @Query()\n        getFirstInterfaceImplementationObject(): BaseInterface {\n          const obj = new FirstImplementation();\n          obj.baseInterfaceField = \"baseInterfaceField\";\n          obj.firstField = \"firstField\";\n          return obj;\n        }\n\n        @Query()\n        getSecondInterfaceWithStringResolveTypeObject(): InterfaceWithStringResolveType {\n          return {\n            baseInterfaceField: \"baseInterfaceField\",\n            secondField: \"secondField\",\n          } as SecondInterfaceWithStringResolveTypeObject;\n        }\n\n        @Query()\n        getSecondInterfaceWithClassResolveTypeObject(): InterfaceWithClassResolveType {\n          return {\n            baseInterfaceField: \"baseInterfaceField\",\n            secondField: \"secondField\",\n          } as SecondInterfaceWithClassResolveTypeObject;\n        }\n\n        @Query()\n        notMatchingValueForInterfaceWithClassResolveTypeObject(): InterfaceWithClassResolveType {\n          return { baseInterfaceField: \"notMatchingValue\" };\n        }\n\n        @Query()\n        queryWithArgs(@Args() args: ChildArgs): boolean {\n          queryArgs = args;\n          return true;\n        }\n\n        @Mutation()\n        mutationWithInput(@Arg(\"input\") input: ChildInput): boolean {\n          mutationInput = input;\n          return true;\n        }\n\n        @Query()\n        baseClassQuery(\n          @Arg(\"input\") input: SampleExtendingNormalClassInput,\n          @Args() args: SampleExtendingNormalClassArgs,\n        ): string {\n          inputFieldValue = input.sampleField;\n          argsFieldValue = args.sampleField;\n          return SampleExtendingNormalClassObject.sampleStaticMethod();\n        }\n\n        @Query()\n        secondImplementationPlainQuery(): SecondImplementation {\n          return {\n            baseInterfaceField: \"baseInterfaceField\",\n            secondField: \"secondField\",\n          };\n        }\n\n        @Query()\n        renamedFieldInterfaceQuery(): BaseInterface {\n          const obj = new FirstImplementation();\n          obj.baseInterfaceField = \"baseInterfaceField\";\n          obj.firstField = \"firstField\";\n          obj.interfaceFieldToBeRenamed = \"interfaceFieldToBeRenamed\";\n          return obj;\n        }\n\n        @Mutation()\n        overwritingInputFieldMutation(@Arg(\"input\") input: SampleSecondExtendedInput): boolean {\n          mutationInput = input;\n          return true;\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [InterfacesResolver],\n        orphanedTypes: [\n          FirstImplementation,\n          SecondInterfaceWithStringResolveTypeObject,\n          FirstInterfaceWithStringResolveTypeObject,\n          SecondInterfaceWithClassResolveTypeObject,\n          FirstInterfaceWithClassResolveTypeObject,\n        ],\n        validate: false,\n      });\n    });\n\n    it(\"should return interface type fields data\", async () => {\n      const query = `query {\n        getFirstInterfaceImplementationObject {\n          baseInterfaceField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data.getFirstInterfaceImplementationObject;\n      expect(data.baseInterfaceField).toEqual(\"baseInterfaceField\");\n    });\n\n    it(\"should correctly recognize returned object type using default `instance of` check\", async () => {\n      const query = `query {\n        getFirstInterfaceImplementationObject {\n          baseInterfaceField\n          ... on FirstImplementation {\n            firstField\n          }\n          ... on SecondImplementation {\n            secondField\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data.getFirstInterfaceImplementationObject;\n      expect(data.baseInterfaceField).toEqual(\"baseInterfaceField\");\n      expect(data.firstField).toEqual(\"firstField\");\n      expect(data.secondField).toBeUndefined();\n    });\n\n    it(\"should correctly recognize returned object type using string provided by `resolveType` function\", async () => {\n      const query = `query {\n        getSecondInterfaceWithStringResolveTypeObject {\n          baseInterfaceField\n          ... on FirstInterfaceWithStringResolveTypeObject {\n            firstField\n          }\n          ... on SecondInterfaceWithStringResolveTypeObject {\n            secondField\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data.getSecondInterfaceWithStringResolveTypeObject;\n      expect(data.baseInterfaceField).toEqual(\"baseInterfaceField\");\n      expect(data.firstField).toBeUndefined();\n      expect(data.secondField).toEqual(\"secondField\");\n    });\n\n    it(\"should correctly recognize returned object type using class provided by `resolveType` function\", async () => {\n      const query = `query {\n        getSecondInterfaceWithClassResolveTypeObject {\n          baseInterfaceField\n          ... on FirstInterfaceWithClassResolveTypeObject {\n            firstField\n          }\n          ... on SecondInterfaceWithClassResolveTypeObject {\n            secondField\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data.getSecondInterfaceWithClassResolveTypeObject;\n      expect(data.baseInterfaceField).toEqual(\"baseInterfaceField\");\n      expect(data.firstField).toBeUndefined();\n      expect(data.secondField).toEqual(\"secondField\");\n    });\n\n    it(\"should should fail with error info when `resolveType` returns undefined\", async () => {\n      const query = `query {\n        notMatchingValueForInterfaceWithClassResolveTypeObject {\n          __typename\n          baseInterfaceField\n          ... on FirstInterfaceWithClassResolveTypeObject {\n            firstField\n          }\n          ... on SecondInterfaceWithClassResolveTypeObject {\n            secondField\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.errors?.[0]?.message).toMatchInlineSnapshot(\n        `\"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.\"`,\n      );\n    });\n\n    it(\"should throw error when not returning instance of object class\", async () => {\n      const query = `query {\n        getInterfacePlainObject {\n          baseInterfaceField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const errorMessage = result.errors![0].message;\n      expect(errorMessage).toContain(\"resolve\");\n      expect(errorMessage).toContain(\"BaseInterface\");\n      expect(errorMessage).toContain(\"instance\");\n      expect(errorMessage).toContain(\"plain\");\n    });\n\n    it(\"should return fields data of object type implementing interface\", async () => {\n      const query = `query {\n        getFirstInterfaceImplementationObject {\n          baseInterfaceField\n          ... on FirstImplementation {\n            firstField\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data.getFirstInterfaceImplementationObject;\n      expect(data.baseInterfaceField).toEqual(\"baseInterfaceField\");\n      expect(data.firstField).toEqual(\"firstField\");\n    });\n\n    it(\"should allow interfaces to specify custom schema names\", async () => {\n      const query = `query {\n        renamedFieldInterfaceQuery {\n          renamedInterfaceField\n        }\n      }`;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      expect((data as any).renamedFieldInterfaceQuery.renamedInterfaceField).toEqual(\n        \"interfaceFieldToBeRenamed\",\n      );\n    });\n\n    it(\"should pass args data of extended args class\", async () => {\n      const query = `query {\n        queryWithArgs(\n          baseArgField: \"baseArgField\"\n          childArgField: \"childArgField\"\n        )\n      }`;\n\n      await graphql({ schema, source: query });\n\n      expect(queryArgs.baseArgField).toEqual(\"baseArgField\");\n      expect(queryArgs.childArgField).toEqual(\"childArgField\");\n      expect(queryArgs.optionalBaseArgField).toEqual(255);\n    });\n\n    it(\"should pass input data of extended input class\", async () => {\n      const query = `mutation {\n        mutationWithInput(input: {\n          baseInputField: \"baseInputField\"\n          childInputField: \"childInputField\"\n        })\n      }`;\n\n      await graphql({ schema, source: query });\n\n      expect(mutationInput.baseInputField).toEqual(\"baseInputField\");\n      expect(mutationInput.childInputField).toEqual(\"childInputField\");\n      expect(mutationInput.optionalBaseInputField).toEqual(255);\n    });\n\n    it(\"should correctly extends non-TypeGraphQL class\", async () => {\n      const query = `query {\n        baseClassQuery(\n          input: { sampleField: \"sampleInputValue\" }\n          sampleField: \"sampleArgValue\"\n        )\n      }`;\n\n      const { data } = await graphql({ schema, source: query });\n\n      expect((data as any).baseClassQuery).toEqual(\"sampleStaticMethod\");\n      expect(inputFieldValue).toEqual(\"sampleInputValue\");\n      expect(argsFieldValue).toEqual(\"sampleArgValue\");\n    });\n\n    it(\"should allow to return plain object when return type is a class that implements an interface\", async () => {\n      const query = `mutation {\n        overwritingInputFieldMutation(input: {\n          baseInputField: {\n            baseField: \"baseField\",\n            extendedField: \"extendedField\",\n          }\n        })\n      }`;\n\n      const { errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      expect(mutationInput).toEqual({\n        baseInputField: {\n          baseField: \"baseField\",\n          extendedField: \"extendedField\",\n        },\n      });\n    });\n\n    it(\"should correctly transform data of overwritten input field\", async () => {\n      const query = `query {\n        secondImplementationPlainQuery {\n          baseInterfaceField\n          secondField\n        }\n      }`;\n\n      const { data, errors } = await graphql({ schema, source: query });\n\n      expect(errors).toBeUndefined();\n      expect((data as any).secondImplementationPlainQuery.baseInterfaceField).toEqual(\n        \"baseInterfaceField\",\n      );\n      expect((data as any).secondImplementationPlainQuery.secondField).toEqual(\"secondField\");\n    });\n  });\n\n  describe(\"Multiple schemas\", () => {\n    beforeEach(() => {\n      getMetadataStorage().clear();\n    });\n\n    it(\"should correctly return data from interface query for all schemas that uses the same interface\", async () => {\n      @InterfaceType()\n      class BaseInterface {\n        @Field()\n        baseField!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class One extends BaseInterface {\n        @Field()\n        one!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class Two extends BaseInterface {\n        @Field()\n        two!: string;\n      }\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => BaseInterface)\n        base(): BaseInterface {\n          const one = new One();\n          one.baseField = \"baseField\";\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          base {\n            __typename\n            baseField\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should correctly return data from interface query for all schemas that uses the same interface when string `resolveType` is provided\", async () => {\n      @InterfaceType({\n        resolveType: value => {\n          if (\"one\" in value) {\n            return \"One\";\n          }\n          if (\"two\" in value) {\n            return \"Two\";\n          }\n          throw new Error(\"Unknown resolveType error\");\n        },\n      })\n      class BaseInterface {\n        @Field()\n        baseField!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class One extends BaseInterface {\n        @Field()\n        one!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class Two extends BaseInterface {\n        @Field()\n        two!: string;\n      }\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => BaseInterface)\n        base(): BaseInterface {\n          const one = new One();\n          one.baseField = \"baseField\";\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          base {\n            __typename\n            baseField\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should correctly return data from interface query for all schemas that uses the same interface when class `resolveType` is provided\", async () => {\n      @InterfaceType({\n        resolveType: value => {\n          if (\"one\" in value) {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            return One;\n          }\n          if (\"two\" in value) {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            return Two;\n          }\n          throw new Error(\"Unknown resolveType error\");\n        },\n      })\n      class BaseInterface {\n        @Field()\n        baseField!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class One extends BaseInterface {\n        @Field()\n        one!: string;\n      }\n      @ObjectType({ implements: [BaseInterface] })\n      class Two extends BaseInterface {\n        @Field()\n        two!: string;\n      }\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => BaseInterface)\n        base(): BaseInterface {\n          const one = new One();\n          one.baseField = \"baseField\";\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          base {\n            __typename\n            baseField\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n        orphanedTypes: [One, Two],\n        validate: false,\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.base).toEqual({\n        __typename: \"One\",\n        baseField: \"baseField\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should by default automatically register all and only the object types that implements an used interface type\", async () => {\n      @InterfaceType()\n      abstract class SampleUnusedInterface {\n        @Field()\n        sampleField!: string;\n      }\n      @ObjectType({ implements: SampleUnusedInterface })\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleUnusedObjectType implements SampleUnusedInterface {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        sampleUnusedInterfaceField!: SampleUnusedInterface;\n      }\n      @InterfaceType()\n      abstract class SampleUsedInterface {\n        @Field()\n        sampleField!: string;\n      }\n      @ObjectType({ implements: SampleUsedInterface })\n      class SampleObjectTypeImplementingUsedInterface implements SampleUsedInterface {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        sampleAdditionalField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleUsedInterface {\n          const sampleObject = new SampleObjectTypeImplementingUsedInterface();\n          sampleObject.sampleField = \"sampleField\";\n          sampleObject.sampleAdditionalField = \"sampleAdditionalField\";\n          return sampleObject;\n        }\n      }\n\n      const { schemaIntrospection } = await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n\n      expect(schemaIntrospection.types).not.toContainEqual(\n        expect.objectContaining({\n          kind: \"OBJECT\",\n          name: \"SampleUnusedObjectType\",\n        }),\n      );\n      expect(schemaIntrospection.types).toContainEqual(\n        expect.objectContaining({\n          kind: \"OBJECT\",\n          name: \"SampleObjectTypeImplementingUsedInterface\",\n        }),\n      );\n    });\n\n    it(\"should by default automatically register all and only the object types that implements an interface type used as field type\", async () => {\n      @InterfaceType()\n      class IFooBar {\n        @Field(() => String)\n        fooBarKind!: string;\n      }\n      @ObjectType({ implements: IFooBar })\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class Foo extends IFooBar {\n        override fooBarKind = \"Foo\";\n      }\n      @ObjectType({ implements: IFooBar })\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class Bar extends IFooBar {\n        override fooBarKind = \"Bar\";\n      }\n      @ObjectType()\n      class FooBar {\n        @Field(() => IFooBar)\n        iFooBarField!: IFooBar;\n      }\n      @Resolver()\n      class TestResolver {\n        @Query(() => FooBar)\n        foobar() {\n          return new FooBar();\n        }\n      }\n      const { schemaIntrospection } = await getSchemaInfo({\n        resolvers: [TestResolver],\n      });\n\n      expect(schemaIntrospection.types).toContainEqual(\n        expect.objectContaining({\n          kind: TypeKind.INTERFACE,\n          name: \"IFooBar\",\n        }),\n      );\n      expect(schemaIntrospection.types).toContainEqual(\n        expect.objectContaining({\n          kind: TypeKind.OBJECT,\n          name: \"Bar\",\n        }),\n      );\n      expect(schemaIntrospection.types).toContainEqual(\n        expect.objectContaining({\n          kind: TypeKind.OBJECT,\n          name: \"Foo\",\n        }),\n      );\n    });\n\n    it(\"should register only the object types from orphanedType when interface type has disabled auto registering\", async () => {\n      @InterfaceType({ autoRegisterImplementations: false })\n      abstract class SampleUsedInterface {\n        @Field()\n        sampleField!: string;\n      }\n      @ObjectType({ implements: SampleUsedInterface })\n      class FirstSampleObject implements SampleUsedInterface {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        sampleFirstAdditionalField!: string;\n      }\n      @ObjectType({ implements: SampleUsedInterface })\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SecondSampleObject implements SampleUsedInterface {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        sampleSecondAdditionalField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleUsedInterface {\n          const sampleObject: FirstSampleObject = {\n            sampleField: \"sampleField\",\n            sampleFirstAdditionalField: \"sampleFirstAdditionalField\",\n          };\n          return sampleObject;\n        }\n      }\n\n      const { schemaIntrospection } = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        orphanedTypes: [FirstSampleObject],\n      });\n\n      expect(schemaIntrospection.types).toContainEqual(\n        expect.objectContaining({\n          kind: \"OBJECT\",\n          name: \"FirstSampleObject\",\n        }),\n      );\n      expect(schemaIntrospection.types).not.toContainEqual(\n        expect.objectContaining({\n          kind: \"OBJECT\",\n          name: \"SecondSampleObject\",\n        }),\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/ioc-container.ts",
    "content": "import \"reflect-metadata\";\nimport { graphql } from \"graphql\";\nimport {\n  Arg,\n  type ContainerType,\n  Field,\n  ObjectType,\n  Query,\n  Resolver,\n  type ResolverData,\n  buildSchema,\n} from \"type-graphql\";\nimport { Container, Service } from \"typedi\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"IOC container\", () => {\n  beforeEach(() => {\n    getMetadataStorage().clear();\n    Container.reset();\n  });\n\n  it(\"should use provided container to load resolver class dependencies\", async () => {\n    let serviceValue: number | undefined;\n    const initValue = 5;\n    @Service()\n    class SampleService {\n      value = initValue;\n    }\n    @ObjectType()\n    class SampleObject {\n      @Field({ nullable: true })\n      field?: string;\n    }\n    @Service()\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      constructor(private service: SampleService) {}\n\n      @Query()\n      sampleQuery(): SampleObject {\n        serviceValue = this.service.value;\n        return {};\n      }\n    }\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n      container: Container,\n    });\n    const query = /* graphql */ `\n      query {\n        sampleQuery {\n          field\n        }\n      }\n    `;\n    await graphql({ schema, source: query });\n\n    expect(serviceValue).toEqual(initValue);\n  });\n\n  it(\"should use default container to instantiate resolver class\", async () => {\n    let resolverValue: number | undefined;\n    @ObjectType()\n    class SampleObject {\n      @Field({ nullable: true })\n      field?: string;\n    }\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      value = Math.random();\n\n      @Query()\n      sampleQuery(): SampleObject {\n        resolverValue = this.value;\n        return {};\n      }\n    }\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n    });\n    const query = /* graphql */ `\n      query {\n        sampleQuery {\n          field\n        }\n      }\n    `;\n    await graphql({ schema, source: query });\n    const firstCallValue = resolverValue;\n    resolverValue = undefined;\n    await graphql({ schema, source: query });\n    const secondCallValue = resolverValue;\n\n    expect(firstCallValue).toBeDefined();\n    expect(secondCallValue).toBeDefined();\n    expect(firstCallValue).toEqual(secondCallValue);\n  });\n\n  it(\"should pass resolver's data to container's get\", async () => {\n    let contextRequestId!: number;\n    const testContainer: ContainerType = {\n      get(someClass, resolverData: ResolverData<{ requestId: number }>) {\n        contextRequestId = resolverData.context.requestId;\n        return Container.get(someClass);\n      },\n    };\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(): string {\n        return \"sampleQuery\";\n      }\n    }\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n      container: testContainer,\n    });\n\n    const query = /* graphql */ `\n      query {\n        sampleQuery\n      }\n    `;\n\n    const requestId = Math.random();\n    await graphql({ schema, source: query, contextValue: { requestId } });\n    expect(contextRequestId).toEqual(requestId);\n  });\n\n  it(\"should properly get container from container getter function\", async () => {\n    let called = false;\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(): string {\n        return \"sampleQuery\";\n      }\n    }\n\n    interface TestContext {\n      container: ContainerType;\n    }\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n      container: ({ context }: ResolverData<TestContext>) => context.container,\n    });\n\n    const query = /* graphql */ `\n      query {\n        sampleQuery\n      }\n    `;\n\n    const mockedContainer: ContainerType = {\n      get(someClass: any) {\n        called = true;\n        return Container.get(someClass);\n      },\n    };\n    const queryContext: TestContext = {\n      container: mockedContainer,\n    };\n\n    await graphql({ schema, source: query, contextValue: queryContext });\n\n    expect(called).toEqual(true);\n  });\n\n  it(\"should properly get instance from an async container\", async () => {\n    let called = false;\n\n    @Service()\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(@Arg(\"sampleArg\") sampleArg: string): string {\n        return sampleArg;\n      }\n    }\n\n    const asyncContainer: ContainerType = {\n      async get(someClass: any) {\n        await new Promise(setImmediate);\n        called = true;\n        return Container.get(someClass);\n      },\n    };\n\n    const schema = await buildSchema({\n      resolvers: [SampleResolver],\n      container: asyncContainer,\n    });\n\n    const query = /* graphql */ `\n      query {\n        sampleQuery(sampleArg: \"sampleArgValue\")\n      }\n    `;\n\n    const result: any = await graphql({ schema, source: query });\n\n    expect(result.errors).toBeUndefined();\n    expect(result.data!.sampleQuery).toEqual(\"sampleArgValue\");\n    expect(called).toEqual(true);\n  });\n});\n"
  },
  {
    "path": "tests/functional/manual-decorators.ts",
    "content": "import \"reflect-metadata\";\nimport { type IntrospectionObjectType } from \"graphql\";\nimport { Args, ArgsType, Field, ObjectType, Query, Resolver } from \"type-graphql\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"manual decorators\", () => {\n  it(\"should not fail when field is dynamically registered\", async () => {\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      manualField!: string;\n    }\n\n    // Dynamically register field\n    Field(() => String)(SampleObject.prototype, \"dynamicField\");\n    @ArgsType()\n    class SampleArgs {\n      @Field()\n      sampleField!: string;\n    }\n    // Dynamically register field args\n    Args(() => SampleArgs)(SampleObject.prototype, \"dynamicField\", 0);\n\n    @Resolver()\n    class SampleResolver {\n      @Query()\n      sampleQuery(): SampleObject {\n        return new SampleObject();\n      }\n    }\n\n    // Get builded schema info from retrospection\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [SampleResolver],\n    });\n    const sampleObjectType = schemaInfo.schemaIntrospection.types.find(\n      type => type.name === \"SampleObject\",\n    ) as IntrospectionObjectType;\n    const dynamicField = sampleObjectType.fields.find(it => it.name === \"dynamicField\")!;\n\n    expect(sampleObjectType.fields).toHaveLength(2);\n    expect(dynamicField.type).toEqual({\n      kind: \"NON_NULL\",\n      name: null,\n      ofType: {\n        kind: \"SCALAR\",\n        name: \"String\",\n        ofType: null,\n      },\n    });\n    expect(dynamicField.args).toEqual([\n      {\n        defaultValue: null,\n        deprecationReason: null,\n        description: null,\n        isDeprecated: false,\n        name: \"sampleField\",\n        type: {\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        },\n      },\n    ]);\n  });\n});\n"
  },
  {
    "path": "tests/functional/metadata-storage.ts",
    "content": "import \"reflect-metadata\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport {\n  type ClassType,\n  Field,\n  FieldResolver,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  Subscription,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"MetadataStorage\", () => {\n  describe(\"resolvers inheritance\", () => {\n    const INHERITED_QUERY_NAME = \"inheritedQueryName\";\n    const INHERITED_MUTATION_NAME = \"inheritedMutationName\";\n    const INHERITED_SUBSCRIPTION_NAME = \"inheritedSubscriptionName\";\n    const INHERITED_FIELD_RESOLVER_NAME = \"inheritedFieldResolverName\";\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      function createAbstractResolver(classType: ClassType) {\n        @Resolver(() => classType)\n        abstract class AbstractResolver {\n          @Query({ name: INHERITED_QUERY_NAME })\n          abstractQuery(): boolean {\n            return true;\n          }\n\n          @Mutation({ name: INHERITED_MUTATION_NAME })\n          abstractMutation(): boolean {\n            return true;\n          }\n\n          @Subscription({ name: INHERITED_SUBSCRIPTION_NAME, topics: \"sampleTopic\" })\n          abstractSubscription(): boolean {\n            return true;\n          }\n\n          @FieldResolver({ name: INHERITED_FIELD_RESOLVER_NAME })\n          abstractFieldResolver(): boolean {\n            return true;\n          }\n        }\n        return AbstractResolver;\n      }\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: boolean;\n\n        @Field({ name: INHERITED_FIELD_RESOLVER_NAME })\n        abstractSampleField!: boolean;\n      }\n\n      @Resolver(() => SampleObject)\n      class SubClassResolver extends createAbstractResolver(SampleObject) {\n        @Query()\n        subClassQuery(): boolean {\n          return true;\n        }\n\n        @Mutation()\n        subClassMutation(): boolean {\n          return true;\n        }\n\n        @Subscription({ topics: \"sampleTopic\" })\n        subClassSubscription(): boolean {\n          return true;\n        }\n\n        @FieldResolver()\n        sampleField(): boolean {\n          return true;\n        }\n      }\n\n      await buildSchema({\n        resolvers: [SubClassResolver],\n        pubSub: createPubSub(),\n      });\n    });\n\n    it(\"should not have duplicated query metadata for inherited resolvers\", async () => {\n      expect(\n        getMetadataStorage().queries.filter(query => query.schemaName === INHERITED_QUERY_NAME),\n      ).toHaveLength(1);\n      expect(getMetadataStorage().queries).toHaveLength(2);\n    });\n\n    it(\"should not have duplicated mutation metadata for inherited resolvers\", async () => {\n      expect(\n        getMetadataStorage().mutations.filter(\n          mutation => mutation.schemaName === INHERITED_MUTATION_NAME,\n        ),\n      ).toHaveLength(1);\n      expect(getMetadataStorage().mutations).toHaveLength(2);\n    });\n\n    it(\"should not have duplicated subscription metadata for inherited resolvers\", async () => {\n      expect(\n        getMetadataStorage().subscriptions.filter(\n          subscription => subscription.schemaName === INHERITED_SUBSCRIPTION_NAME,\n        ),\n      ).toHaveLength(1);\n      expect(getMetadataStorage().subscriptions).toHaveLength(2);\n    });\n\n    it(\"should not have duplicated fieldResolver metadata for inherited resolvers\", async () => {\n      expect(\n        getMetadataStorage().fieldResolvers.filter(\n          fieldResolver => fieldResolver.schemaName === INHERITED_FIELD_RESOLVER_NAME,\n        ),\n      ).toHaveLength(1);\n      expect(getMetadataStorage().fieldResolvers).toHaveLength(2);\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/middlewares.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, graphql } from \"graphql\";\nimport {\n  Arg,\n  Field,\n  FieldResolver,\n  type MiddlewareFn,\n  type MiddlewareInterface,\n  type NextFn,\n  ObjectType,\n  Query,\n  Resolver,\n  type ResolverData,\n  UseMiddleware,\n  buildSchema,\n} from \"type-graphql\";\nimport { createMethodMiddlewareDecorator } from \"@/decorators\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"Middlewares\", () => {\n  let schema: GraphQLSchema;\n  let sampleResolver: any;\n  let middlewareLogs: string[] = [];\n  const sleep = (time: number) =>\n    new Promise(resolve => {\n      setTimeout(resolve, time);\n    });\n\n  const resolverMiddleware1: MiddlewareFn = async (_, next) => {\n    middlewareLogs.push(\"resolver middleware1 before\");\n    const result = await next();\n    middlewareLogs.push(\"resolver middleware1 after\");\n    return result;\n  };\n\n  const resolverMiddleware2: MiddlewareFn = async (_, next) => {\n    middlewareLogs.push(\"resolver middleware2 before\");\n    const result = await next();\n    middlewareLogs.push(\"resolver middleware2 after\");\n    return result;\n  };\n\n  beforeEach(() => {\n    middlewareLogs = [];\n  });\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    const middleware1: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"middleware1 before\");\n      const result = await next();\n      middlewareLogs.push(\"middleware1 after\");\n      return result;\n    };\n    const middleware2: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"middleware2 before\");\n      const result = await next();\n      middlewareLogs.push(\"middleware2 after\");\n      return result;\n    };\n    const middleware3: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"middleware3 before\");\n      const result = await next();\n      middlewareLogs.push(\"middleware3 after\");\n      return result;\n    };\n    const interceptMiddleware: MiddlewareFn = async (_, next) => {\n      const result = await next();\n      middlewareLogs.push(result);\n      return \"interceptMiddleware\";\n    };\n    const returnUndefinedMiddleware: MiddlewareFn = async (_, next) => {\n      const result = await next();\n      middlewareLogs.push(result);\n    };\n    const errorCatchMiddleware: MiddlewareFn = async (_, next) => {\n      try {\n        const result = await next();\n        return result;\n      } catch (err) {\n        middlewareLogs.push((err as Error).message);\n        return \"errorCatchMiddleware\";\n      }\n    };\n    const errorThrowAfterMiddleware: MiddlewareFn = async (_, next) => {\n      await next();\n      middlewareLogs.push(\"errorThrowAfterMiddleware\");\n      throw new Error(\"errorThrowAfterMiddleware\");\n    };\n    const errorThrowMiddleware: MiddlewareFn = async _ => {\n      middlewareLogs.push(\"errorThrowMiddleware\");\n      throw new Error(\"errorThrowMiddleware\");\n    };\n    const fieldResolverMiddleware: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"fieldResolverMiddlewareBefore\");\n      const result = await next();\n      middlewareLogs.push(\"fieldResolverMiddlewareAfter\");\n      return result;\n    };\n    const doubleNextMiddleware: MiddlewareFn = async (_, next) => {\n      const result1 = await next();\n      await next();\n      return result1;\n    };\n\n    class ClassMiddleware implements MiddlewareInterface {\n      private logName = \"ClassMiddleware\";\n\n      async use(_: ResolverData, next: NextFn) {\n        middlewareLogs.push(`${this.logName} before`);\n        const result = await next();\n        middlewareLogs.push(`${this.logName} after`);\n        return result;\n      }\n    }\n    const CustomMethodDecorator = createMethodMiddlewareDecorator(async (_, next) => {\n      middlewareLogs.push(\"CustomMethodDecorator\");\n      return next();\n    });\n\n    @ObjectType()\n    class SampleObject {\n      @Field()\n      normalField!: string;\n\n      @Field()\n      resolverField!: string;\n\n      @Field()\n      @UseMiddleware(fieldResolverMiddleware)\n      middlewareField!: string;\n    }\n\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      @Query()\n      normalQuery(): boolean {\n        return true;\n      }\n\n      @Query()\n      sampleObjectQuery(): SampleObject {\n        return {\n          normalField: \"normalField\",\n          middlewareField: \"middlewareField\",\n        } as SampleObject;\n      }\n\n      @Query(() => String)\n      @UseMiddleware(middleware1, middleware2, middleware3)\n      async middlewareOrderQuery() {\n        middlewareLogs.push(\"middlewareOrderQuery\");\n        await sleep(25);\n        return \"middlewareOrderQueryResult\";\n      }\n\n      @UseMiddleware(middleware1)\n      @UseMiddleware(middleware2)\n      @UseMiddleware(middleware3)\n      @Query(() => String)\n      async multipleMiddlewareDecoratorsQuery() {\n        middlewareLogs.push(\"multipleMiddlewareDecoratorsQuery\");\n        return \"multipleMiddlewareDecoratorsQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(interceptMiddleware)\n      middlewareInterceptQuery(): string {\n        middlewareLogs.push(\"middlewareInterceptQuery\");\n        return \"middlewareInterceptQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(\n        returnUndefinedMiddleware,\n        returnUndefinedMiddleware,\n        returnUndefinedMiddleware,\n      )\n      middlewareReturnUndefinedQuery(): string {\n        middlewareLogs.push(\"middlewareReturnUndefinedQuery\");\n        return \"middlewareReturnUndefinedQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(errorCatchMiddleware)\n      middlewareErrorCatchQuery(@Arg(\"throwError\") throwError: boolean): string {\n        middlewareLogs.push(\"middlewareErrorCatchQuery\");\n        if (throwError) {\n          throw new Error(\"middlewareErrorCatchQueryError\");\n        }\n        return \"middlewareErrorCatchQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(errorThrowAfterMiddleware)\n      middlewareThrowErrorAfterQuery(): string {\n        middlewareLogs.push(\"middlewareThrowErrorAfterQuery\");\n        return \"middlewareThrowErrorAfterQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(errorThrowMiddleware)\n      middlewareThrowErrorQuery(): string {\n        middlewareLogs.push(\"middlewareThrowErrorQuery\");\n        return \"middlewareThrowErrorQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(doubleNextMiddleware)\n      doubleNextMiddlewareQuery(): string {\n        middlewareLogs.push(\"doubleNextMiddlewareQuery\");\n        return \"doubleNextMiddlewareQueryResult\";\n      }\n\n      @Query()\n      @UseMiddleware(ClassMiddleware)\n      classMiddlewareQuery(): string {\n        middlewareLogs.push(\"classMiddlewareQuery\");\n        return \"classMiddlewareQueryResult\";\n      }\n\n      @Query()\n      @CustomMethodDecorator\n      customMethodDecoratorQuery(): string {\n        middlewareLogs.push(\"customMethodDecoratorQuery\");\n        return \"customMethodDecoratorQuery\";\n      }\n\n      @FieldResolver()\n      @UseMiddleware(fieldResolverMiddleware)\n      resolverField(): string {\n        middlewareLogs.push(\"resolverField\");\n        return \"resolverField\";\n      }\n    }\n\n    sampleResolver = SampleResolver;\n    schema = await buildSchema({\n      resolvers: [SampleResolver],\n    });\n  });\n\n  it(\"should build the schema without errors\", async () => {\n    expect(schema).toBeDefined();\n  });\n\n  it(\"should correctly returns value from normal query\", async () => {\n    const query = `query {\n      normalQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).normalQuery).toEqual(true);\n  });\n\n  it(\"should correctly call middlewares in order\", async () => {\n    const query = `query {\n      middlewareOrderQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).middlewareOrderQuery).toEqual(\"middlewareOrderQueryResult\");\n\n    expect(middlewareLogs).toHaveLength(7);\n    expect(middlewareLogs[0]).toEqual(\"middleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"middleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"middleware3 before\");\n    expect(middlewareLogs[3]).toEqual(\"middlewareOrderQuery\");\n    expect(middlewareLogs[4]).toEqual(\"middleware3 after\");\n    expect(middlewareLogs[5]).toEqual(\"middleware2 after\");\n    expect(middlewareLogs[6]).toEqual(\"middleware1 after\");\n  });\n\n  it(\"should correctly call resolver middlewares in order\", async () => {\n    UseMiddleware(resolverMiddleware1, resolverMiddleware2)(sampleResolver);\n    const localSchema = await buildSchema({\n      resolvers: [sampleResolver],\n    });\n\n    // clear ResolverMiddlewareMetadata for other tests\n    getMetadataStorage().resolverMiddlewares = [];\n    getMetadataStorage().resolverMiddlewaresByTargetCache = new Map();\n    getMetadataStorage().middlewaresByTargetAndFieldCache = new Map();\n\n    const query = `query {\n      middlewareOrderQuery\n    }`;\n\n    const { data } = await graphql({ schema: localSchema, source: query });\n\n    expect(data!.middlewareOrderQuery).toEqual(\"middlewareOrderQueryResult\");\n\n    expect(middlewareLogs).toHaveLength(11);\n    expect(middlewareLogs[0]).toEqual(\"resolver middleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"resolver middleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"middleware1 before\");\n    expect(middlewareLogs[3]).toEqual(\"middleware2 before\");\n    expect(middlewareLogs[4]).toEqual(\"middleware3 before\");\n    expect(middlewareLogs[5]).toEqual(\"middlewareOrderQuery\");\n    expect(middlewareLogs[6]).toEqual(\"middleware3 after\");\n    expect(middlewareLogs[7]).toEqual(\"middleware2 after\");\n    expect(middlewareLogs[8]).toEqual(\"middleware1 after\");\n    expect(middlewareLogs[9]).toEqual(\"resolver middleware2 after\");\n    expect(middlewareLogs[10]).toEqual(\"resolver middleware1 after\");\n  });\n\n  it(\"should call middlewares in order of multiple decorators\", async () => {\n    const query = `query {\n      multipleMiddlewareDecoratorsQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).multipleMiddlewareDecoratorsQuery).toEqual(\n      \"multipleMiddlewareDecoratorsQueryResult\",\n    );\n\n    expect(middlewareLogs).toHaveLength(7);\n    expect(middlewareLogs[0]).toEqual(\"middleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"middleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"middleware3 before\");\n    expect(middlewareLogs[3]).toEqual(\"multipleMiddlewareDecoratorsQuery\");\n    expect(middlewareLogs[4]).toEqual(\"middleware3 after\");\n    expect(middlewareLogs[5]).toEqual(\"middleware2 after\");\n    expect(middlewareLogs[6]).toEqual(\"middleware1 after\");\n  });\n\n  it(\"should call resolver middlewares in order of multiple decorators\", async () => {\n    @UseMiddleware(resolverMiddleware1)\n    @UseMiddleware(resolverMiddleware2)\n    @Resolver()\n    class LocalResolver {\n      @Query()\n      normalQuery(): boolean {\n        middlewareLogs.push(\"normalQuery\");\n        return true;\n      }\n    }\n    const localSchema = await buildSchema({\n      resolvers: [LocalResolver],\n    });\n    const query = `query {\n      normalQuery\n    }`;\n\n    const { data } = await graphql({ schema: localSchema, source: query });\n\n    expect(data!.normalQuery).toEqual(true);\n\n    expect(middlewareLogs).toHaveLength(5);\n    expect(middlewareLogs[0]).toEqual(\"resolver middleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"resolver middleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"normalQuery\");\n    expect(middlewareLogs[3]).toEqual(\"resolver middleware2 after\");\n    expect(middlewareLogs[4]).toEqual(\"resolver middleware1 after\");\n  });\n\n  it(\"should correctly intercept returned value\", async () => {\n    const query = `query {\n      middlewareInterceptQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).middlewareInterceptQuery).toEqual(\"interceptMiddleware\");\n    expect(middlewareLogs).toHaveLength(2);\n    expect(middlewareLogs[0]).toEqual(\"middlewareInterceptQuery\");\n    expect(middlewareLogs[1]).toEqual(\"middlewareInterceptQueryResult\");\n  });\n\n  it(\"should correctly use next middleware value when undefined returned\", async () => {\n    const query = `query {\n      middlewareReturnUndefinedQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).middlewareReturnUndefinedQuery).toEqual(\n      \"middlewareReturnUndefinedQueryResult\",\n    );\n    expect(middlewareLogs).toHaveLength(4);\n    expect(middlewareLogs[0]).toEqual(\"middlewareReturnUndefinedQuery\");\n    expect(middlewareLogs[1]).toEqual(\"middlewareReturnUndefinedQueryResult\");\n    expect(middlewareLogs[2]).toEqual(\"middlewareReturnUndefinedQueryResult\");\n    expect(middlewareLogs[3]).toEqual(\"middlewareReturnUndefinedQueryResult\");\n  });\n\n  it(\"should correctly catch error thrown in resolver\", async () => {\n    const query = `query {\n      middlewareErrorCatchQuery(throwError: true)\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).middlewareErrorCatchQuery).toEqual(\"errorCatchMiddleware\");\n    expect(middlewareLogs).toHaveLength(2);\n    expect(middlewareLogs[0]).toEqual(\"middlewareErrorCatchQuery\");\n    expect(middlewareLogs[1]).toEqual(\"middlewareErrorCatchQueryError\");\n  });\n\n  it(\"should not modify the response if error not thrown\", async () => {\n    const query = `query {\n      middlewareErrorCatchQuery(throwError: false)\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).middlewareErrorCatchQuery).toEqual(\"middlewareErrorCatchQueryResult\");\n  });\n\n  it(\"should propagate thrown error up to graphql handler\", async () => {\n    const query = `query {\n      middlewareThrowErrorAfterQuery\n    }`;\n\n    const { errors } = await graphql({ schema, source: query });\n\n    expect(errors).toHaveLength(1);\n    expect(errors![0].message).toEqual(\"errorThrowAfterMiddleware\");\n    expect(middlewareLogs).toHaveLength(2);\n    expect(middlewareLogs[0]).toEqual(\"middlewareThrowErrorAfterQuery\");\n    expect(middlewareLogs[1]).toEqual(\"errorThrowAfterMiddleware\");\n  });\n\n  it(\"should prevent calling handler when `next` not invoked\", async () => {\n    const query = `query {\n      middlewareThrowErrorQuery\n    }`;\n\n    const { errors } = await graphql({ schema, source: query });\n\n    expect(errors).toHaveLength(1);\n    expect(errors![0].message).toEqual(\"errorThrowMiddleware\");\n    expect(middlewareLogs).toHaveLength(1);\n    expect(middlewareLogs[0]).toEqual(\"errorThrowMiddleware\");\n  });\n\n  it(\"should call middlewares for field resolver\", async () => {\n    const query = `query {\n      sampleObjectQuery {\n        resolverField\n      }\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).sampleObjectQuery.resolverField).toEqual(\"resolverField\");\n    expect(middlewareLogs).toHaveLength(3);\n    expect(middlewareLogs[0]).toEqual(\"fieldResolverMiddlewareBefore\");\n    expect(middlewareLogs[1]).toEqual(\"resolverField\");\n    expect(middlewareLogs[2]).toEqual(\"fieldResolverMiddlewareAfter\");\n  });\n\n  it(\"should correctly call class middleware\", async () => {\n    const query = `query {\n      classMiddlewareQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).classMiddlewareQuery).toEqual(\"classMiddlewareQueryResult\");\n    expect(middlewareLogs).toHaveLength(3);\n    expect(middlewareLogs[0]).toEqual(\"ClassMiddleware before\");\n    expect(middlewareLogs[1]).toEqual(\"classMiddlewareQuery\");\n    expect(middlewareLogs[2]).toEqual(\"ClassMiddleware after\");\n  });\n\n  it(\"should correctly call resolver of custom method decorator\", async () => {\n    const query = `query {\n      customMethodDecoratorQuery\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).customMethodDecoratorQuery).toEqual(\"customMethodDecoratorQuery\");\n    expect(middlewareLogs).toHaveLength(2);\n    expect(middlewareLogs[0]).toEqual(\"CustomMethodDecorator\");\n    expect(middlewareLogs[1]).toEqual(\"customMethodDecoratorQuery\");\n  });\n\n  it(\"should call middlewares for normal field\", async () => {\n    const query = `query {\n      sampleObjectQuery {\n        middlewareField\n      }\n    }`;\n\n    const { data } = await graphql({ schema, source: query });\n\n    expect((data as any).sampleObjectQuery.middlewareField).toEqual(\"middlewareField\");\n    expect(middlewareLogs).toHaveLength(2);\n    expect(middlewareLogs[0]).toEqual(\"fieldResolverMiddlewareBefore\");\n    expect(middlewareLogs[1]).toEqual(\"fieldResolverMiddlewareAfter\");\n  });\n\n  it(\"should throw error if middleware called next more than once\", async () => {\n    const query = `query {\n      doubleNextMiddlewareQuery\n    }`;\n\n    const { errors } = await graphql({ schema, source: query });\n\n    expect(errors).toHaveLength(1);\n    expect(errors![0].message).toEqual(\"next() called multiple times\");\n  });\n\n  it(\"should correctly call middlewares in the order of global, resolver, field\", async () => {\n    const globalMiddleware1: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"globalMiddleware1 before\");\n      const result = await next();\n      middlewareLogs.push(\"globalMiddleware1 after\");\n      return result;\n    };\n    const globalMiddleware2: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"globalMiddleware2 before\");\n      const result = await next();\n      middlewareLogs.push(\"globalMiddleware2 after\");\n      return result;\n    };\n    const localSchema = await buildSchema({\n      resolvers: [sampleResolver],\n      globalMiddlewares: [globalMiddleware1, globalMiddleware2],\n    });\n    const query = `query {\n      middlewareOrderQuery\n    }`;\n\n    const { data } = await graphql({ schema: localSchema, source: query });\n\n    expect((data as any).middlewareOrderQuery).toEqual(\"middlewareOrderQueryResult\");\n    expect(middlewareLogs).toHaveLength(11);\n    expect(middlewareLogs[0]).toEqual(\"globalMiddleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"globalMiddleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"middleware1 before\");\n    expect(middlewareLogs[3]).toEqual(\"middleware2 before\");\n    expect(middlewareLogs[4]).toEqual(\"middleware3 before\");\n    expect(middlewareLogs[5]).toEqual(\"middlewareOrderQuery\");\n    expect(middlewareLogs[6]).toEqual(\"middleware3 after\");\n    expect(middlewareLogs[7]).toEqual(\"middleware2 after\");\n    expect(middlewareLogs[8]).toEqual(\"middleware1 after\");\n    expect(middlewareLogs[9]).toEqual(\"globalMiddleware2 after\");\n    expect(middlewareLogs[10]).toEqual(\"globalMiddleware1 after\");\n  });\n\n  it(\"should correctly call global middlewares before local ones\", async () => {\n    UseMiddleware(resolverMiddleware1, resolverMiddleware2)(sampleResolver);\n    const globalMiddleware1: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"globalMiddleware1 before\");\n      const result = await next();\n      middlewareLogs.push(\"globalMiddleware1 after\");\n      return result;\n    };\n    const globalMiddleware2: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"globalMiddleware2 before\");\n      const result = await next();\n      middlewareLogs.push(\"globalMiddleware2 after\");\n      return result;\n    };\n    const localSchema = await buildSchema({\n      resolvers: [sampleResolver],\n      globalMiddlewares: [globalMiddleware1, globalMiddleware2],\n    });\n\n    // clear ResolverMiddlewareMetadata for other tests\n    getMetadataStorage().resolverMiddlewares = [];\n\n    const query = `query {\n      middlewareOrderQuery\n    }`;\n\n    const { data } = await graphql({ schema: localSchema, source: query });\n\n    expect(data!.middlewareOrderQuery).toEqual(\"middlewareOrderQueryResult\");\n\n    expect(middlewareLogs).toHaveLength(15);\n    expect(middlewareLogs[0]).toEqual(\"globalMiddleware1 before\");\n    expect(middlewareLogs[1]).toEqual(\"globalMiddleware2 before\");\n    expect(middlewareLogs[2]).toEqual(\"resolver middleware1 before\");\n    expect(middlewareLogs[3]).toEqual(\"resolver middleware2 before\");\n    expect(middlewareLogs[4]).toEqual(\"middleware1 before\");\n    expect(middlewareLogs[5]).toEqual(\"middleware2 before\");\n    expect(middlewareLogs[6]).toEqual(\"middleware3 before\");\n    expect(middlewareLogs[7]).toEqual(\"middlewareOrderQuery\");\n    expect(middlewareLogs[8]).toEqual(\"middleware3 after\");\n    expect(middlewareLogs[9]).toEqual(\"middleware2 after\");\n    expect(middlewareLogs[10]).toEqual(\"middleware1 after\");\n    expect(middlewareLogs[11]).toEqual(\"resolver middleware2 after\");\n    expect(middlewareLogs[12]).toEqual(\"resolver middleware1 after\");\n    expect(middlewareLogs[13]).toEqual(\"globalMiddleware2 after\");\n    expect(middlewareLogs[14]).toEqual(\"globalMiddleware1 after\");\n  });\n});\n"
  },
  {
    "path": "tests/functional/nested-interface-inheritance.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, printSchema } from \"graphql\";\nimport { Field, InterfaceType, ObjectType, Query, Resolver } from \"../../src\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"nested interface inheritance\", () => {\n  let schema: GraphQLSchema;\n  beforeAll(async () => {\n    @InterfaceType()\n    abstract class A {\n      @Field()\n      a!: string;\n    }\n\n    @InterfaceType({ implements: A })\n    abstract class B extends A {\n      @Field()\n      b!: string;\n    }\n\n    @InterfaceType({ implements: B })\n    abstract class C extends B {\n      @Field()\n      c!: string;\n    }\n\n    @ObjectType({ implements: C })\n    class D extends C {\n      @Field()\n      d!: string;\n    }\n\n    @Resolver()\n    class TestResolver {\n      @Query()\n      testQuery(): string {\n        return \"testQuery\";\n      }\n    }\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [TestResolver],\n      orphanedTypes: [A, B, C, D],\n    });\n    schema = schemaInfo.schema;\n  });\n\n  it(\"should properly generate object type, implementing multi-inherited interface, with only one `implements`\", async () => {\n    expect(printSchema(schema)).toMatchInlineSnapshot(`\n      \"type D implements C & B & A {\n        a: String!\n        b: String!\n        c: String!\n        d: String!\n      }\n\n      interface A {\n        a: String!\n      }\n\n      interface B implements A {\n        a: String!\n        b: String!\n      }\n\n      interface C implements B & A {\n        a: String!\n        b: String!\n        c: String!\n      }\n\n      type Query {\n        testQuery: String!\n      }\"\n    `);\n  });\n});\n"
  },
  {
    "path": "tests/functional/peer-dependency.ts",
    "content": "import { ensureInstalledCorrectGraphQLPackage } from \"@/utils/graphql-version\";\n\ndescribe(\"`graphql` package peer dependency\", () => {\n  it(\"should have installed correct version\", async () => {\n    expect(ensureInstalledCorrectGraphQLPackage).not.toThrow();\n  });\n});\n"
  },
  {
    "path": "tests/functional/query-complexity.ts",
    "content": "import \"reflect-metadata\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport { type GraphQLSchema, parse } from \"graphql\";\nimport { fieldExtensionsEstimator, getComplexity, simpleEstimator } from \"graphql-query-complexity\";\nimport {\n  Arg,\n  type ClassType,\n  Field,\n  ObjectType,\n  Query,\n  Resolver,\n  Subscription,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\n// Helpers\nfunction calculateComplexityPoints(query: string, schema: GraphQLSchema) {\n  const complexityPoints = getComplexity({\n    query: parse(query),\n    schema,\n    estimators: [fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 })],\n  });\n\n  return complexityPoints;\n}\n\ndescribe(\"Query complexity\", () => {\n  describe(\"Queries\", () => {\n    let schema: GraphQLSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ complexity: 10 })\n        complexResolverMethod!: number;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleObject {\n          const obj = new SampleObject();\n          return obj;\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n    });\n\n    it(\"should build the schema without errors\", () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should properly calculate complexity points for a query with complex field resolver\", () => {\n      const query = /* graphql */ `\n        query {\n          sampleQuery {\n            complexResolverMethod\n          }\n        }\n      `;\n      const points = calculateComplexityPoints(query, schema);\n\n      expect(points).toEqual(11);\n    });\n  });\n\n  describe(\"Subscriptions\", () => {\n    let schema: GraphQLSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        normalField!: string;\n      }\n\n      function createResolver(name: string, objectType: ClassType) {\n        @Resolver(() => objectType)\n        class BaseResolver {\n          protected name = \"baseName\";\n\n          @Query({ name: `${name}Query` })\n          baseQuery(@Arg(\"arg\") _arg: boolean): boolean {\n            return true;\n          }\n\n          @Subscription({ topics: \"baseTopic\", name: `${name}Subscription` })\n          baseSubscription(@Arg(\"arg\") _arg: boolean): boolean {\n            return true;\n          }\n        }\n\n        return BaseResolver;\n      }\n\n      @Resolver()\n      class ChildResolver extends createResolver(\"prefix\", SampleObject) {\n        @Subscription({ topics: \"childTopic\", complexity: 4 })\n        childSubscription(): boolean {\n          return true;\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [ChildResolver],\n        pubSub: createPubSub(),\n      });\n\n      schema = schemaInfo.schema;\n    });\n\n    it(\"should build schema correctly\", async () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should properly calculate subscription complexity\", () => {\n      const query = `subscription {\n        childSubscription\n      }`;\n\n      const points = calculateComplexityPoints(query, schema);\n\n      expect(points).toEqual(4);\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/resolvers.ts",
    "content": "/* eslint \"@typescript-eslint/no-this-alias\": [\"error\", { \"allowedNames\": [\"self\"] }] */\nimport \"reflect-metadata\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionField,\n  type IntrospectionInputObjectType,\n  type IntrospectionListTypeRef,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  CannotDetermineGraphQLTypeError,\n  type ClassType,\n  ConflictingDefaultValuesError,\n  Ctx,\n  Field,\n  FieldResolver,\n  Info,\n  InputType,\n  Int,\n  Mutation,\n  NoExplicitTypeError,\n  ObjectType,\n  Query,\n  Resolver,\n  type ResolverInterface,\n  Root,\n  Subscription,\n  WrongNullableListOptionError,\n  buildSchema,\n  buildSchemaSync,\n  createParameterDecorator,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { type ReturnTypeFunc } from \"../../src/decorators/types\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\nimport { getInnerTypeOfNonNullableType } from \"../helpers/getInnerFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Resolvers\", () => {\n  describe(\"Schema\", () => {\n    let schemaIntrospection: IntrospectionSchema;\n    let queryType: IntrospectionObjectType;\n    let mutationType: IntrospectionObjectType;\n    let sampleObjectType: IntrospectionObjectType;\n    let argMethodField: IntrospectionField;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        field!: string;\n\n        @Field({ defaultValue: \"defaultStringFieldDefaultValue\" })\n        defaultStringField!: string;\n\n        @Field()\n        implicitDefaultStringField: string = \"implicitDefaultStringFieldDefaultValue\";\n\n        @Field()\n        inheritDefaultField: string = \"inheritDefaultFieldValue\";\n      }\n\n      @InputType()\n      class SampleInputChild extends SampleInput {\n        @Field({ defaultValue: \"defaultValueOverwritten\" })\n        override defaultStringField!: string;\n\n        @Field()\n        override implicitDefaultStringField: string = \"implicitDefaultValueOverwritten\";\n      }\n\n      @ArgsType()\n      class SampleArgs {\n        @Field()\n        stringArg!: string;\n\n        @Field(() => Int, { nullable: true })\n        numberArg!: number;\n\n        @Field()\n        inputObjectArg!: SampleInput;\n\n        @Field({ defaultValue: \"defaultStringArgDefaultValue\" })\n        defaultStringArg!: string;\n\n        @Field()\n        implicitDefaultStringArg: string = \"implicitDefaultStringArgDefaultValue\";\n\n        @Field()\n        inheritDefaultArg: string = \"inheritDefaultArgValue\";\n      }\n\n      @ArgsType()\n      class SampleArgsChild extends SampleArgs {\n        @Field({ defaultValue: \"defaultValueOverwritten\" })\n        override defaultStringArg!: string;\n\n        @Field()\n        override implicitDefaultStringArg: string = \"implicitDefaultValueOverwritten\";\n      }\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        normalField!: string;\n\n        @Field()\n        resolverFieldWithArgs!: string;\n\n        @Field()\n        // eslint-disable-next-line @typescript-eslint/class-literal-property-style\n        get getterField(): string {\n          return \"getterField\";\n        }\n\n        @Field()\n        simpleMethodField(): string {\n          return \"simpleMethodField\";\n        }\n\n        @Field(() => String)\n        argMethodField(\n          @Arg(\"stringArg\") _stringArg: string,\n          @Arg(\"booleanArg\") _booleanArg: boolean,\n          @Arg(\"numberArg\") _numberArg: number,\n          @Arg(\"inputArg\") _inputArg: SampleInput,\n          @Arg(\"inputChildArg\") _inputChildArg: SampleInputChild,\n          @Arg(\"explicitNullableArg\", _type => String, { nullable: true })\n          _explicitNullableArg: any,\n          @Arg(\"explicitArrayArg\", () => [String]) _explicitArrayArg: any,\n          @Arg(\"defaultStringArg\", { defaultValue: \"defaultStringArgDefaultValue\" })\n          _defaultStringArg: string,\n          @Arg(\"nullableStringArg\", { nullable: true }) _nullableStringArg?: string,\n        ): any {\n          return \"argMethodField\";\n        }\n      }\n\n      @Resolver(() => SampleObject)\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class LambdaResolver {\n        @Query()\n        lambdaQuery(): boolean {\n          return true;\n        }\n      }\n\n      @Resolver(SampleObject)\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class ClassResolver {\n        @Query()\n        classQuery(): boolean {\n          return true;\n        }\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        emptyQuery(): boolean {\n          return true;\n        }\n\n        @Query()\n        implicitStringQuery(): string {\n          return \"implicitStringQuery\";\n        }\n\n        @Query(() => String)\n        explicitStringQuery(): any {\n          return \"explicitStringQuery\";\n        }\n\n        @Query(() => String, { nullable: true })\n        nullableStringQuery(): string | null {\n          return Math.random() > 0.5 ? \"explicitStringQuery\" : null;\n        }\n\n        @Query(() => [String])\n        explicitStringArrayQuery(): any {\n          return [];\n        }\n\n        @Query(() => [String], { nullable: \"items\" })\n        explicitNullableItemArrayQuery(): any {\n          return [];\n        }\n\n        @Query(() => [String], { nullable: \"itemsAndList\" })\n        explicitNullableArrayWithNullableItemsQuery(): any {\n          return [];\n        }\n\n        @Query(() => String)\n        async promiseStringQuery(): Promise<string> {\n          return \"promiseStringQuery\";\n        }\n\n        @Query()\n        implicitObjectQuery(): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query(() => SampleObject)\n        async asyncObjectQuery(): Promise<SampleObject> {\n          return {} as SampleObject;\n        }\n\n        @Query()\n        rootCtxQuery(@Root() _root: any, @Ctx() _ctx: any): boolean {\n          return true;\n        }\n\n        @Query(() => String)\n        argQuery(@Arg(\"arg1\") _arg1: string, @Arg(\"arg2\") _arg2: boolean): any {\n          return \"argQuery\";\n        }\n\n        @Query(() => String)\n        argsQuery(@Args() _args: SampleArgs): any {\n          return \"argsQuery\";\n        }\n\n        @Query(() => String)\n        argAndArgsQuery(@Arg(\"arg1\") _arg1: string, @Args() _args: SampleArgs): any {\n          return \"argAndArgsQuery\";\n        }\n\n        @Query(() => String)\n        argsInheritanceQuery(@Args() _args: SampleArgsChild): any {\n          return \"argsInheritanceQuery\";\n        }\n\n        @Mutation()\n        emptyMutation(): boolean {\n          return true;\n        }\n\n        @FieldResolver()\n        resolverFieldWithArgs(@Arg(\"arg1\") _arg1: string, @Arg(\"arg2\") _arg2: boolean) {\n          return \"resolverFieldWithArgs\";\n        }\n\n        @FieldResolver(() => String, { nullable: true, description: \"independent\" })\n        independentFieldResolver(@Arg(\"arg1\") _arg1: string, @Arg(\"arg2\") _arg2: boolean) {\n          return \"resolverFieldWithArgs\";\n        }\n\n        @FieldResolver(() => String, { name: \"overwrittenField\", nullable: true })\n        overwrittenFieldResolver() {\n          return \"overwrittenFieldResolver\";\n        }\n      }\n\n      // get builded schema info from retrospection\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      queryType = schemaInfo.queryType;\n      mutationType = schemaInfo.mutationType!;\n      sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n      argMethodField = sampleObjectType.fields.find(field => field.name === \"argMethodField\")!;\n    });\n\n    // helpers\n    function getQuery(queryName: string) {\n      return queryType.fields.find(field => field.name === queryName)!;\n    }\n    function getMutation(mutationName: string) {\n      return mutationType.fields.find(field => field.name === mutationName)!;\n    }\n\n    it(\"should generate schema without errors\", async () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    describe(\"Fields\", () => {\n      it(\"should generate proper field type for property getter\", async () => {\n        const getterField = sampleObjectType.fields.find(field => field.name === \"getterField\")!;\n        const getterFieldType = getterField.type as IntrospectionNonNullTypeRef;\n        const getterFieldInnerType = getterFieldType.ofType as IntrospectionNamedTypeRef;\n\n        expect(getterField.name).toEqual(\"getterField\");\n        expect(getterField.args).toHaveLength(0);\n        expect(getterFieldType.kind).toEqual(TypeKind.NON_NULL);\n        expect(getterFieldInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(getterFieldInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate proper field type for simple class method\", async () => {\n        const simpleMethodField = sampleObjectType.fields.find(\n          field => field.name === \"simpleMethodField\",\n        )!;\n        const simpleMethodFieldType = simpleMethodField.type as IntrospectionNonNullTypeRef;\n        const simpleMethodFieldInnerType =\n          simpleMethodFieldType.ofType as IntrospectionNamedTypeRef;\n\n        expect(simpleMethodField.name).toEqual(\"simpleMethodField\");\n        expect(simpleMethodField.args).toHaveLength(0);\n        expect(simpleMethodFieldType.kind).toEqual(TypeKind.NON_NULL);\n        expect(simpleMethodFieldInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(simpleMethodFieldInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate proper field type for class method with args\", async () => {\n        const argMethodFieldType = argMethodField.type as IntrospectionNonNullTypeRef;\n        const argMethodFieldInnerType = argMethodFieldType.ofType as IntrospectionNamedTypeRef;\n\n        expect(argMethodField.name).toEqual(\"argMethodField\");\n        expect(argMethodField.args).toHaveLength(9);\n        expect(argMethodFieldType.kind).toEqual(TypeKind.NON_NULL);\n        expect(argMethodFieldInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(argMethodFieldInnerType.name).toEqual(\"String\");\n      });\n    });\n\n    describe(\"Inline args\", () => {\n      it(\"should generate normal string arg type for object field method\", async () => {\n        const stringArg = argMethodField.args.find(arg => arg.name === \"stringArg\")!;\n        const stringArgType = stringArg.type as IntrospectionNonNullTypeRef;\n        const stringArgInnerType = stringArgType.ofType as IntrospectionNamedTypeRef;\n\n        expect(stringArg.name).toEqual(\"stringArg\");\n        expect(stringArgType.kind).toEqual(TypeKind.NON_NULL);\n        expect(stringArgInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(stringArgInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate normal boolean arg type for object field method\", async () => {\n        const booleanArg = argMethodField.args.find(arg => arg.name === \"booleanArg\")!;\n        const booleanArgType = booleanArg.type as IntrospectionNonNullTypeRef;\n        const booleanArgInnerType = booleanArgType.ofType as IntrospectionNamedTypeRef;\n\n        expect(booleanArg.name).toEqual(\"booleanArg\");\n        expect(booleanArgType.kind).toEqual(TypeKind.NON_NULL);\n        expect(booleanArgInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(booleanArgInnerType.name).toEqual(\"Boolean\");\n      });\n\n      it(\"should generate normal number arg type for object field method\", async () => {\n        const numberArg = argMethodField.args.find(arg => arg.name === \"numberArg\")!;\n        const numberArgType = numberArg.type as IntrospectionNonNullTypeRef;\n        const numberArgInnerType = numberArgType.ofType as IntrospectionNamedTypeRef;\n\n        expect(numberArg.name).toEqual(\"numberArg\");\n        expect(numberArgType.kind).toEqual(TypeKind.NON_NULL);\n        expect(numberArgInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(numberArgInnerType.name).toEqual(\"Float\");\n      });\n\n      it(\"should generate nullable string arg type for object field method when explicitly sets\", async () => {\n        const explicitNullableArg = argMethodField.args.find(\n          arg => arg.name === \"explicitNullableArg\",\n        )!;\n        const explicitNullableArgType = explicitNullableArg.type as IntrospectionNamedTypeRef;\n\n        expect(explicitNullableArg.name).toEqual(\"explicitNullableArg\");\n        expect(explicitNullableArgType.kind).toEqual(TypeKind.SCALAR);\n        expect(explicitNullableArgType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate string array arg type for object field method when explicitly sets\", async () => {\n        const explicitArrayArg = argMethodField.args.find(arg => arg.name === \"explicitArrayArg\")!;\n        const explicitArrayArgType = explicitArrayArg.type as IntrospectionNonNullTypeRef;\n        const explicitArrayArgArrayType = explicitArrayArgType.ofType as IntrospectionListTypeRef;\n        const explicitArrayArgInnerType =\n          explicitArrayArgArrayType.ofType as IntrospectionNonNullTypeRef;\n        const explicitArrayArgArrayItemType =\n          explicitArrayArgInnerType.ofType as IntrospectionNamedTypeRef;\n\n        expect(explicitArrayArg.name).toEqual(\"explicitArrayArg\");\n        expect(explicitArrayArgType.kind).toEqual(TypeKind.NON_NULL);\n        expect(explicitArrayArgArrayType.kind).toEqual(TypeKind.LIST);\n        expect(explicitArrayArgInnerType.kind).toEqual(TypeKind.NON_NULL);\n        expect(explicitArrayArgArrayItemType.kind).toEqual(TypeKind.SCALAR);\n        expect(explicitArrayArgArrayItemType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate nullable string arg type for object field method\", async () => {\n        const nullableStringArg = argMethodField.args.find(\n          arg => arg.name === \"nullableStringArg\",\n        )!;\n        const nullableStringArgType = nullableStringArg.type as IntrospectionNamedTypeRef;\n\n        expect(nullableStringArg.name).toEqual(\"nullableStringArg\");\n        expect(nullableStringArgType.kind).toEqual(TypeKind.SCALAR);\n        expect(nullableStringArgType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate input object arg type for object field method\", async () => {\n        const inputArg = argMethodField.args.find(arg => arg.name === \"inputArg\")!;\n        const inputArgType = inputArg.type as IntrospectionNonNullTypeRef;\n        const inputArgInnerType = inputArgType.ofType as IntrospectionNamedTypeRef;\n\n        expect(inputArg.name).toEqual(\"inputArg\");\n        expect(inputArgType.kind).toEqual(TypeKind.NON_NULL);\n        expect(inputArgInnerType.kind).toEqual(TypeKind.INPUT_OBJECT);\n        expect(inputArgInnerType.name).toEqual(\"SampleInput\");\n      });\n\n      it(\"should generate non-nullable string arg type with defaultValue for object field method\", async () => {\n        const inputArg = argMethodField.args.find(arg => arg.name === \"defaultStringArg\")!;\n        const defaultValueStringArgType = inputArg.type as IntrospectionNamedTypeRef;\n\n        expect(inputArg.defaultValue).toBe('\"defaultStringArgDefaultValue\"');\n        expect(defaultValueStringArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n    });\n\n    describe(\"Input object\", () => {\n      let sampleInputType: IntrospectionInputObjectType;\n      let sampleInputChildType: IntrospectionInputObjectType;\n\n      beforeAll(() => {\n        sampleInputType = schemaIntrospection.types.find(\n          field => field.name === \"SampleInput\",\n        )! as IntrospectionInputObjectType;\n        sampleInputChildType = schemaIntrospection.types.find(\n          field => field.name === \"SampleInputChild\",\n        )! as IntrospectionInputObjectType;\n      });\n\n      it(\"should generate non-nullable string arg type with defaultValue for input object field\", async () => {\n        const defaultValueStringField = sampleInputType.inputFields.find(\n          arg => arg.name === \"defaultStringField\",\n        )!;\n        const defaultValueStringFieldType =\n          defaultValueStringField.type as IntrospectionNamedTypeRef;\n\n        expect(defaultValueStringField.defaultValue).toBe('\"defaultStringFieldDefaultValue\"');\n        expect(defaultValueStringFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should generate non-nullable string arg type with implicit defaultValue for input object field\", async () => {\n        const implicitDefaultValueStringField = sampleInputType.inputFields.find(\n          arg => arg.name === \"implicitDefaultStringField\",\n        )!;\n        const implicitDefaultValueStringFieldType =\n          implicitDefaultValueStringField.type as IntrospectionNamedTypeRef;\n\n        expect(implicitDefaultValueStringField.defaultValue).toBe(\n          '\"implicitDefaultStringFieldDefaultValue\"',\n        );\n        expect(implicitDefaultValueStringFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should overwrite defaultValue in child input object\", async () => {\n        const defaultValueStringField = sampleInputChildType.inputFields.find(\n          arg => arg.name === \"defaultStringField\",\n        )!;\n        const defaultValueStringFieldType =\n          defaultValueStringField.type as IntrospectionNamedTypeRef;\n\n        expect(defaultValueStringField.defaultValue).toBe('\"defaultValueOverwritten\"');\n        expect(defaultValueStringFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should overwrite implicit defaultValue in child input object\", async () => {\n        const implicitDefaultValueStringField = sampleInputChildType.inputFields.find(\n          arg => arg.name === \"implicitDefaultStringField\",\n        )!;\n        const implicitDefaultValueStringFieldType =\n          implicitDefaultValueStringField.type as IntrospectionNamedTypeRef;\n\n        expect(implicitDefaultValueStringField.defaultValue).toBe(\n          '\"implicitDefaultValueOverwritten\"',\n        );\n        expect(implicitDefaultValueStringFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should inherit field with defaultValue from parent\", async () => {\n        const inheritDefaultField = sampleInputChildType.inputFields.find(\n          arg => arg.name === \"inheritDefaultField\",\n        )!;\n        const inheritDefaultFieldType = inheritDefaultField.type as IntrospectionNamedTypeRef;\n\n        expect(inheritDefaultField.defaultValue).toBe('\"inheritDefaultFieldValue\"');\n        expect(inheritDefaultFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n    });\n\n    describe(\"Args object\", () => {\n      it(\"should generate simple arg from args object field\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n        const stringArg = argsQuery.args.find(arg => arg.name === \"stringArg\")!;\n        const stringArgInnerType = (stringArg.type as IntrospectionNonNullTypeRef)\n          .ofType as IntrospectionNamedTypeRef;\n\n        expect(stringArg.name).toEqual(\"stringArg\");\n        expect(stringArgInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(stringArgInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate non-nullable type arg with defaultValue from args object field\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n        const defaultStringArg = argsQuery.args.find(arg => arg.name === \"defaultStringArg\")!;\n        const defaultStringArgType = defaultStringArg.type as IntrospectionNamedTypeRef;\n\n        expect(defaultStringArg.name).toEqual(\"defaultStringArg\");\n        expect(defaultStringArg.defaultValue).toEqual('\"defaultStringArgDefaultValue\"');\n        expect(defaultStringArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should overwrite defaultValue in child args object field\", async () => {\n        const argsQuery = getQuery(\"argsInheritanceQuery\");\n        const defaultStringArg = argsQuery.args.find(arg => arg.name === \"defaultStringArg\")!;\n        const defaultStringArgType = defaultStringArg.type as IntrospectionNamedTypeRef;\n\n        expect(defaultStringArg.name).toEqual(\"defaultStringArg\");\n        expect(defaultStringArg.defaultValue).toEqual('\"defaultValueOverwritten\"');\n        expect(defaultStringArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should overwrite implicit defaultValue in child args object field\", async () => {\n        const argsQuery = getQuery(\"argsInheritanceQuery\");\n        const implicitDefaultStringArg = argsQuery.args.find(\n          arg => arg.name === \"implicitDefaultStringArg\",\n        )!;\n        const implicitDefaultStringArgType =\n          implicitDefaultStringArg.type as IntrospectionNamedTypeRef;\n\n        expect(implicitDefaultStringArg.name).toEqual(\"implicitDefaultStringArg\");\n        expect(implicitDefaultStringArg.defaultValue).toEqual('\"implicitDefaultValueOverwritten\"');\n        expect(implicitDefaultStringArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should inherit defaultValue field from parent args object field\", async () => {\n        const argsQuery = getQuery(\"argsInheritanceQuery\");\n        const inheritDefaultArg = argsQuery.args.find(arg => arg.name === \"inheritDefaultArg\")!;\n        const inheritDefaultArgType = inheritDefaultArg.type as IntrospectionNamedTypeRef;\n\n        expect(inheritDefaultArg.name).toEqual(\"inheritDefaultArg\");\n        expect(inheritDefaultArg.defaultValue).toEqual('\"inheritDefaultArgValue\"');\n        expect(inheritDefaultArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should generate non-nullable type arg with implicit defaultValue from args object field\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n        const implicitDefaultStringArg = argsQuery.args.find(\n          arg => arg.name === \"implicitDefaultStringArg\",\n        )!;\n        const implicitDefaultStringArgType =\n          implicitDefaultStringArg.type as IntrospectionNamedTypeRef;\n\n        expect(implicitDefaultStringArg.name).toEqual(\"implicitDefaultStringArg\");\n        expect(implicitDefaultStringArg.defaultValue).toEqual(\n          '\"implicitDefaultStringArgDefaultValue\"',\n        );\n        expect(implicitDefaultStringArgType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n      });\n\n      it(\"should generate nullable type arg from args object field\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n        const numberArg = argsQuery.args.find(arg => arg.name === \"numberArg\")!;\n        const numberArgType = numberArg.type as IntrospectionNamedTypeRef;\n\n        expect(numberArg.name).toEqual(\"numberArg\");\n        expect(numberArgType.kind).toEqual(TypeKind.SCALAR);\n        expect(numberArgType.name).toEqual(\"Int\");\n      });\n\n      it(\"should generate input object type arg from args object field\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n        const inputObjectArg = argsQuery.args.find(arg => arg.name === \"inputObjectArg\")!;\n        const inputObjectArgInnerType = (inputObjectArg.type as IntrospectionNonNullTypeRef)\n          .ofType as IntrospectionNamedTypeRef;\n\n        expect(inputObjectArg.name).toEqual(\"inputObjectArg\");\n        expect(inputObjectArgInnerType.kind).toEqual(TypeKind.INPUT_OBJECT);\n        expect(inputObjectArgInnerType.name).toEqual(\"SampleInput\");\n      });\n\n      it(\"should generate field args from field resolver args definition\", async () => {\n        const resolverFieldWithArgs = sampleObjectType.fields.find(\n          field => field.name === \"resolverFieldWithArgs\",\n        )!;\n\n        const fieldResolverArgs = resolverFieldWithArgs.args;\n        expect(fieldResolverArgs).toHaveLength(2);\n\n        const arg1 = fieldResolverArgs.find(arg => arg.name === \"arg1\")!;\n        const arg1InnerType = (arg1.type as IntrospectionNonNullTypeRef)\n          .ofType as IntrospectionNamedTypeRef;\n        const arg2 = fieldResolverArgs.find(arg => arg.name === \"arg2\")!;\n        const arg2InnerType = (arg2.type as IntrospectionNonNullTypeRef)\n          .ofType as IntrospectionNamedTypeRef;\n\n        expect(arg1InnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(arg1InnerType.name).toEqual(\"String\");\n        expect(arg2InnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(arg2InnerType.name).toEqual(\"Boolean\");\n      });\n\n      it(\"should generate object field type from independent field resolver\", async () => {\n        const independentFieldResolver = sampleObjectType.fields.find(\n          field => field.name === \"independentFieldResolver\",\n        )!;\n        const fieldResolverArgs = independentFieldResolver.args;\n        const arg1Type = getInnerTypeOfNonNullableType(\n          fieldResolverArgs.find(arg => arg.name === \"arg1\")!,\n        );\n        const arg2Type = getInnerTypeOfNonNullableType(\n          fieldResolverArgs.find(arg => arg.name === \"arg2\")!,\n        );\n        const independentFieldResolverType =\n          independentFieldResolver.type as IntrospectionNamedTypeRef;\n\n        expect(independentFieldResolver.description).toEqual(\"independent\");\n        expect(independentFieldResolverType.kind).toEqual(\"SCALAR\");\n        expect(independentFieldResolverType.name).toEqual(\"String\");\n        expect(fieldResolverArgs).toHaveLength(2);\n        expect(arg1Type.kind).toEqual(TypeKind.SCALAR);\n        expect(arg1Type.name).toEqual(\"String\");\n        expect(arg2Type.kind).toEqual(TypeKind.SCALAR);\n        expect(arg2Type.name).toEqual(\"Boolean\");\n      });\n\n      it(\"should overwrite object field name from field resolver decorator option\", async () => {\n        const overwrittenField = sampleObjectType.fields.find(\n          field => field.name === \"overwrittenField\",\n        )!;\n        const overwrittenFieldResolver = sampleObjectType.fields.find(\n          field => field.name === \"overwrittenFieldResolver\",\n        )!;\n        const independentFieldResolverType = overwrittenField.type as IntrospectionNamedTypeRef;\n\n        expect(overwrittenFieldResolver).toBeUndefined();\n        expect(independentFieldResolverType.kind).toEqual(\"SCALAR\");\n        expect(independentFieldResolverType.name).toEqual(\"String\");\n      });\n    });\n\n    describe(\"Handlers\", () => {\n      it(\"should generate proper definition for query method\", async () => {\n        const emptyQuery = getQuery(\"emptyQuery\");\n        const emptyQueryReturnType = emptyQuery.type as IntrospectionNonNullTypeRef;\n        const emptyQueryInnerReturnType = emptyQueryReturnType.ofType as IntrospectionNamedTypeRef;\n\n        expect(emptyQuery.args).toHaveLength(0);\n        expect(emptyQuery.name).toEqual(\"emptyQuery\");\n        expect(emptyQueryReturnType.kind).toEqual(TypeKind.NON_NULL);\n        expect(emptyQueryInnerReturnType.kind).toEqual(TypeKind.SCALAR);\n        expect(emptyQueryInnerReturnType.name).toEqual(\"Boolean\");\n      });\n\n      it(\"should generate proper definition for mutation method\", async () => {\n        const emptyMutation = getMutation(\"emptyMutation\");\n        const emptyMutationReturnType = emptyMutation.type as IntrospectionNonNullTypeRef;\n        const emptyMutationInnerReturnType =\n          emptyMutationReturnType.ofType as IntrospectionNamedTypeRef;\n\n        expect(emptyMutation.args).toHaveLength(0);\n        expect(emptyMutation.name).toEqual(\"emptyMutation\");\n        expect(emptyMutationReturnType.kind).toEqual(TypeKind.NON_NULL);\n        expect(emptyMutationInnerReturnType.kind).toEqual(TypeKind.SCALAR);\n        expect(emptyMutationInnerReturnType.name).toEqual(\"Boolean\");\n      });\n\n      it(\"should generate implicit string return type for query method\", async () => {\n        const implicitStringQuery = getQuery(\"implicitStringQuery\");\n        const implicitStringQueryType = implicitStringQuery.type as IntrospectionNonNullTypeRef;\n        const implicitStringQueryInnerType =\n          implicitStringQueryType.ofType as IntrospectionNamedTypeRef;\n\n        expect(implicitStringQueryInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(implicitStringQueryInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate string return type for query when explicitly set\", async () => {\n        const explicitStringQuery = getQuery(\"explicitStringQuery\");\n        const explicitStringQueryType = explicitStringQuery.type as IntrospectionNonNullTypeRef;\n        const explicitStringQueryInnerType =\n          explicitStringQueryType.ofType as IntrospectionNamedTypeRef;\n\n        expect(explicitStringQueryInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(explicitStringQueryInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate nullable string return type for query when explicitly set\", async () => {\n        const nullableStringQuery = getQuery(\"nullableStringQuery\");\n        const nullableStringQueryType = nullableStringQuery.type as IntrospectionNamedTypeRef;\n\n        expect(nullableStringQueryType.kind).toEqual(TypeKind.SCALAR);\n        expect(nullableStringQueryType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate explicit array string return type for query\", async () => {\n        const explicitStringArrayQuery = getQuery(\"explicitStringArrayQuery\");\n        const type = explicitStringArrayQuery.type as IntrospectionNonNullTypeRef;\n        const listType = type.ofType as IntrospectionListTypeRef;\n        const nonNullItemType = listType.ofType as IntrospectionNonNullTypeRef;\n        const itemType = nonNullItemType.ofType as IntrospectionNamedTypeRef;\n\n        expect(listType.kind).toEqual(TypeKind.LIST);\n        expect(itemType.kind).toEqual(TypeKind.SCALAR);\n        expect(itemType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate explicit array of nullable string return type for query\", async () => {\n        const explicitNullableItemArrayQuery = getQuery(\"explicitNullableItemArrayQuery\");\n        const type = explicitNullableItemArrayQuery.type as IntrospectionNonNullTypeRef;\n        const listType = type.ofType as IntrospectionListTypeRef;\n        const itemType = listType.ofType as IntrospectionNamedTypeRef;\n\n        expect(type.kind).toEqual(TypeKind.NON_NULL);\n        expect(listType.kind).toEqual(TypeKind.LIST);\n        expect(itemType.kind).toEqual(TypeKind.SCALAR);\n        expect(itemType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate explicit nullable array of nullable string return type for query\", async () => {\n        const explicitNullableArrayWithNullableItemsQuery = getQuery(\n          \"explicitNullableArrayWithNullableItemsQuery\",\n        );\n        const listType =\n          explicitNullableArrayWithNullableItemsQuery.type as IntrospectionListTypeRef;\n        const itemType = listType.ofType as IntrospectionNamedTypeRef;\n\n        expect(listType.kind).toEqual(TypeKind.LIST);\n        expect(itemType.kind).toEqual(TypeKind.SCALAR);\n        expect(itemType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate string return type for query returning Promise\", async () => {\n        const promiseStringQuery = getQuery(\"promiseStringQuery\");\n        const promiseStringQueryType = promiseStringQuery.type as IntrospectionNonNullTypeRef;\n        const promiseStringQueryInnerType =\n          promiseStringQueryType.ofType as IntrospectionNamedTypeRef;\n\n        expect(promiseStringQueryInnerType.kind).toEqual(TypeKind.SCALAR);\n        expect(promiseStringQueryInnerType.name).toEqual(\"String\");\n      });\n\n      it(\"should generate object return type for query returning promise\", async () => {\n        const asyncObjectQuery = getQuery(\"asyncObjectQuery\");\n        const asyncObjectQueryType = asyncObjectQuery.type as IntrospectionNonNullTypeRef;\n        const asyncObjectQueryInnerType = asyncObjectQueryType.ofType as IntrospectionNamedTypeRef;\n\n        expect(asyncObjectQueryInnerType.kind).toEqual(TypeKind.OBJECT);\n        expect(asyncObjectQueryInnerType.name).toEqual(\"SampleObject\");\n      });\n\n      it(\"should generate object return type for query method\", async () => {\n        const implicitObjectQuery = getQuery(\"implicitObjectQuery\");\n        const implicitObjectQueryType = implicitObjectQuery.type as IntrospectionNonNullTypeRef;\n        const implicitObjectQueryInnerType =\n          implicitObjectQueryType.ofType as IntrospectionNamedTypeRef;\n\n        expect(implicitObjectQueryInnerType.kind).toEqual(TypeKind.OBJECT);\n        expect(implicitObjectQueryInnerType.name).toEqual(\"SampleObject\");\n      });\n\n      it(\"should not generate args type for query using @Root and @Ctx decorators\", async () => {\n        const rootCtxQuery = getQuery(\"rootCtxQuery\");\n\n        expect(rootCtxQuery.args).toHaveLength(0);\n      });\n\n      it(\"should generate proper definition for query with @Arg\", async () => {\n        const argQuery = getQuery(\"argQuery\");\n\n        expect(argQuery.name).toEqual(\"argQuery\");\n        expect(argQuery.args).toHaveLength(2);\n      });\n\n      it(\"should generate proper definition for query with @Args\", async () => {\n        const argsQuery = getQuery(\"argsQuery\");\n\n        expect(argsQuery.name).toEqual(\"argsQuery\");\n        expect(argsQuery.args).toHaveLength(6);\n      });\n\n      it(\"should generate proper definition for query with both @Arg and @Args\", async () => {\n        const argAndArgsQuery = getQuery(\"argAndArgsQuery\");\n\n        expect(argAndArgsQuery.name).toEqual(\"argAndArgsQuery\");\n        expect(argAndArgsQuery.args).toHaveLength(7);\n      });\n    });\n\n    describe(\"Errors\", () => {\n      beforeEach(() => {\n        getMetadataStorage().clear();\n      });\n\n      it(\"should throw error when arg type is not correct\", async () => {\n        const error = await expectToThrow(() => {\n          @Resolver()\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          class SampleResolverWithError {\n            @Query(() => String)\n            sampleQuery(@Arg(\"arg\") _arg: any): string {\n              return \"sampleQuery\";\n            }\n          }\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'arg' of 'sampleQuery' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error when query return type not provided\", async () => {\n        const error = await expectToThrow(() => {\n          @Resolver()\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery() {\n              return \"sampleQuery\";\n            }\n          }\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error when provided query return type is not correct\", async () => {\n        const error = await expectToThrow(() => {\n          @Resolver()\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery(): any {\n              return \"sampleQuery\";\n            }\n          }\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error when mutation return type not provided\", async () => {\n        const error = await expectToThrow(() => {\n          @Resolver()\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          class SampleResolverWithError {\n            @Mutation()\n            sampleMutation() {\n              return \"sampleMutation\";\n            }\n          }\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error provided mutation return type is not correct\", async () => {\n        const error = await expectToThrow(() => {\n          @Resolver()\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          class SampleResolverWithError {\n            @Mutation()\n            sampleMutation(): any {\n              return \"sampleMutation\";\n            }\n          }\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error when creating field resolver in resolver with no object type info\", async () => {\n        const error = await expectToThrow(async () => {\n          @Resolver()\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery(): string {\n              return \"sampleQuery\";\n            }\n\n            @FieldResolver()\n            sampleField() {\n              return \"sampleField\";\n            }\n          }\n\n          await buildSchema({\n            resolvers: [SampleResolverWithError],\n          });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"No provided object type in '@Resolver' decorator for class 'SampleResolverWithError!'\"`,\n        );\n      });\n\n      it(\"should throw error when creating independent field resolver with no type info\", async () => {\n        const error = await expectToThrow(async () => {\n          @ObjectType()\n          class SampleObjectWithError {\n            @Field()\n            sampleField!: string;\n          }\n          @Resolver(() => SampleObjectWithError)\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery(): string {\n              return \"sampleQuery\";\n            }\n\n            @FieldResolver()\n            independentField() {\n              return \"independentField\";\n            }\n          }\n\n          await buildSchema({\n            resolvers: [SampleResolverWithError],\n          });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(NoExplicitTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'independentField' of 'SampleResolverWithError' class.\"`,\n        );\n      });\n\n      it(\"should throw error when using undecorated class as an explicit type\", async () => {\n        const error = await expectToThrow(async () => {\n          class SampleUndecoratedObject {\n            sampleField!: string;\n          }\n          @Resolver()\n          class SampleResolverWithError {\n            @Query(() => SampleUndecoratedObject)\n            sampleQuery(): string {\n              return \"sampleQuery\";\n            }\n          }\n\n          await buildSchema({\n            resolvers: [SampleResolverWithError],\n          });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(CannotDetermineGraphQLTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"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?\"`,\n        );\n      });\n\n      it(\"should throw error when using object type class is used as explicit type in place of input type\", async () => {\n        const error = await expectToThrow(async () => {\n          @ObjectType()\n          class SampleObject {\n            @Field()\n            sampleField!: string;\n          }\n          @Resolver()\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery(@Arg(\"input\") _input: SampleObject): string {\n              return \"sampleQuery\";\n            }\n          }\n\n          await buildSchema({\n            resolvers: [SampleResolverWithError],\n          });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(CannotDetermineGraphQLTypeError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"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?\"`,\n        );\n      });\n\n      it(\"should throw error when using object type class is used as explicit type in place of args type\", async () => {\n        const error = await expectToThrow(async () => {\n          @ObjectType()\n          class SampleObject {\n            @Field()\n            sampleField!: string;\n          }\n          @Resolver()\n          class SampleResolverWithError {\n            @Query()\n            sampleQuery(@Args() _args: SampleObject): string {\n              return \"sampleQuery\";\n            }\n          }\n\n          await buildSchema({\n            resolvers: [SampleResolverWithError],\n          });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"The value used as a type of '@Args' for 'sampleQuery' of 'SampleResolverWithError' is not a class decorated with '@ArgsType' decorator!\"`,\n        );\n      });\n\n      it(\"should throw error when declared default values are not equal\", async () => {\n        const error = await expectToThrow(async () => {\n          @InputType()\n          class SampleInput {\n            @Field({ defaultValue: \"decoratorDefaultValue\" })\n            inputField: string = \"initializerDefaultValue\";\n          }\n\n          @Resolver()\n          class SampleResolver {\n            @Query()\n            sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n              return \"sampleQuery\";\n            }\n          }\n\n          await buildSchema({ resolvers: [SampleResolver] });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(ConflictingDefaultValuesError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"The 'inputField' field of 'SampleInput' has conflicting default values. Default value from decorator ('decoratorDefaultValue') is not equal to the property initializer value ('initializerDefaultValue').\"`,\n        );\n      });\n\n      it(\"should throw error when list nullable option is combined with non-list type\", async () => {\n        const error = await expectToThrow(async () => {\n          @InputType()\n          class SampleInput {\n            @Field({ nullable: \"items\" })\n            inputField!: string;\n          }\n\n          @Resolver()\n          class SampleResolver {\n            @Query()\n            sampleQuery(@Arg(\"input\") _input: SampleInput): string {\n              return \"sampleQuery\";\n            }\n          }\n\n          const resolvers = [SampleResolver] as const;\n          await buildSchema({ resolvers });\n        });\n\n        expect(error).toBeInstanceOf(Error);\n        expect(error).toBeInstanceOf(WrongNullableListOptionError);\n        expect(error.message).toMatchInlineSnapshot(\n          `\"Wrong nullable option set for SampleInput#inputField. You cannot combine non-list type with nullable 'items'.\"`,\n        );\n      });\n    });\n  });\n\n  describe(\"Functional\", () => {\n    const classes: any = {};\n    let schema: GraphQLSchema;\n\n    let queryRoot: any;\n    let queryContext: any;\n    let queryInfo: any;\n    let queryFirstCustom: any;\n    let querySecondCustom: any;\n    let queryThirdCustom: any;\n    let descriptorEvaluated: boolean;\n    let sampleObjectConstructorCallCount: number;\n\n    function DescriptorDecorator(): MethodDecorator {\n      return (_, __, descriptor: any) => {\n        const originalMethod: Function = descriptor.value;\n        // eslint-disable-next-line no-param-reassign\n        descriptor.value = (...args: unknown[]) => {\n          descriptorEvaluated = true;\n          return originalMethod.apply(null, ...args);\n        };\n      };\n    }\n\n    let mutationInputValue: any;\n    beforeEach(() => {\n      queryRoot = undefined;\n      queryContext = undefined;\n      queryInfo = undefined;\n      queryFirstCustom = undefined;\n      querySecondCustom = undefined;\n      queryThirdCustom = undefined;\n      descriptorEvaluated = false;\n      sampleObjectConstructorCallCount = 0;\n      mutationInputValue = undefined;\n    });\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      const FirstCustomArgDecorator = () => createParameterDecorator(resolverData => resolverData);\n      const SecondCustomArgDecorator = (arg: string) => createParameterDecorator(async () => arg);\n      const DefaultValueArgDecorator = (\n        argName: string,\n        typeFunc: ReturnTypeFunc,\n        defaultValue: any,\n      ) =>\n        createParameterDecorator(resolverData => resolverData.args[argName] ?? defaultValue, {\n          arg: {\n            name: argName,\n            typeFunc,\n            options: { nullable: true },\n          },\n        });\n\n      @ArgsType()\n      class SampleArgs {\n        private readonly TRUE = true;\n\n        instanceField = Math.random();\n\n        @Field()\n        factor!: number;\n\n        isTrue() {\n          return this.TRUE;\n        }\n      }\n      classes.SampleArgs = SampleArgs;\n\n      @ArgsType()\n      class SampleOptionalArgs {\n        @Field()\n        stringField!: string;\n\n        @Field({ nullable: true })\n        optionalField?: string;\n      }\n      classes.SampleOptionalArgs = SampleOptionalArgs;\n\n      @InputType()\n      class SampleInput {\n        private readonly TRUE = true;\n\n        instanceField = Math.random();\n\n        @Field()\n        factor!: number;\n\n        isTrue() {\n          return this.TRUE;\n        }\n      }\n      classes.SampleInput = SampleInput;\n\n      @InputType()\n      class SampleNestedInput {\n        instanceField = Math.random();\n\n        @Field()\n        nestedField!: SampleInput;\n\n        @Field({ nullable: true })\n        optionalNestedField?: SampleInput;\n\n        @Field(() => [SampleInput])\n        nestedArrayField!: SampleInput[];\n\n        @Field(() => [SampleInput], { nullable: \"itemsAndList\" })\n        nestedOptionalArrayField?: Array<SampleInput | undefined>;\n      }\n      classes.SampleNestedInput = SampleNestedInput;\n\n      @InputType()\n      class SampleTripleNestedInput {\n        instanceField = Math.random();\n\n        @Field(() => [[[SampleInput]]])\n        deeplyNestedInputArrayField!: SampleInput[][][];\n      }\n      classes.SampleTripleNestedInput = SampleTripleNestedInput;\n\n      @ArgsType()\n      class SampleNestedArgs {\n        @Field()\n        factor!: number;\n\n        @Field()\n        input!: SampleInput;\n      }\n      classes.SampleNestedArgs = SampleNestedArgs;\n\n      @ObjectType()\n      class SampleObject {\n        private readonly TRUE = true;\n\n        isTrue() {\n          return this.TRUE;\n        }\n\n        constructor() {\n          sampleObjectConstructorCallCount += 1;\n        }\n\n        instanceValue = Math.random();\n\n        @Field()\n        fieldResolverField!: number;\n\n        @Field()\n        fieldResolverGetter!: number;\n\n        @Field({ complexity: 5 })\n        fieldResolverMethod!: number;\n\n        @Field()\n        fieldResolverMethodWithArgs!: number;\n\n        @Field()\n        fieldResolverWithRoot!: number;\n\n        @Field({ complexity: 10 })\n        complexResolverMethod!: number;\n\n        @Field()\n        get getterField(): number {\n          return this.instanceValue;\n        }\n\n        @Field()\n        methodField(): number {\n          return this.instanceValue;\n        }\n\n        @Field(() => String)\n        async asyncMethodField() {\n          return \"asyncMethodField\";\n        }\n\n        @Field()\n        methodFieldWithArg(@Arg(\"factor\") factor: number): number {\n          return this.instanceValue * factor;\n        }\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver implements ResolverInterface<SampleObject> {\n        factor = 1;\n\n        randomValueField = Math.random() * this.factor;\n\n        get randomValueGetter() {\n          return Math.random() * this.factor;\n        }\n\n        getRandomValue() {\n          return Math.random() * this.factor;\n        }\n\n        @Query()\n        sampleQuery(): SampleObject {\n          const obj = new SampleObject();\n          return obj;\n        }\n\n        @Query()\n        notInstanceQuery(): SampleObject {\n          return {} as SampleObject;\n        }\n\n        @Query()\n        queryWithRootContextAndInfo(\n          @Root() root: any,\n          @Ctx() context: any,\n          @Info() info: any,\n        ): boolean {\n          queryRoot = root;\n          queryContext = context;\n          queryInfo = info;\n          return true;\n        }\n\n        @Query()\n        queryWithPartialRootAndContext(\n          @Root(\"rootField\") rootField: any,\n          @Ctx(\"contextField\") contextField: any,\n        ): boolean {\n          queryRoot = rootField;\n          queryContext = contextField;\n          return true;\n        }\n\n        @Query()\n        queryWithCustomDecorators(\n          @FirstCustomArgDecorator() firstCustom: any,\n          @SecondCustomArgDecorator(\"secondCustom\") secondCustom: any,\n          @DefaultValueArgDecorator(\"thirdCustom\", () => String, \"Default\")\n          thirdCustom: string,\n        ): boolean {\n          queryFirstCustom = firstCustom;\n          querySecondCustom = secondCustom;\n          queryThirdCustom = thirdCustom;\n          return true;\n        }\n\n        @Query()\n        @DescriptorDecorator()\n        queryWithCustomDescriptorDecorator(): boolean {\n          return true;\n        }\n\n        @Mutation()\n        mutationWithArgs(@Args() args: SampleArgs): number {\n          if (args.isTrue()) {\n            return args.factor * args.instanceField;\n          }\n\n          return -1.0;\n        }\n\n        @Mutation()\n        mutationWithOptionalArgs(@Args() args: SampleOptionalArgs): boolean {\n          mutationInputValue = args;\n          return true;\n        }\n\n        @Mutation()\n        mutationWithInput(@Arg(\"input\") input: SampleInput): number {\n          if (input.isTrue()) {\n            return input.factor * input.instanceField;\n          }\n\n          return -1.0;\n        }\n\n        @Mutation()\n        mutationWithNestedInputs(@Arg(\"input\") input: SampleNestedInput): number {\n          mutationInputValue = input;\n          return input.instanceField;\n        }\n\n        @Mutation()\n        mutationWithTripleNestedInputs(@Arg(\"input\") input: SampleTripleNestedInput): number {\n          mutationInputValue = input;\n          return input.deeplyNestedInputArrayField[0][0][0].factor;\n        }\n\n        @Mutation()\n        mutationWithNestedArgsInput(@Args() { factor, input }: SampleNestedArgs): number {\n          mutationInputValue = input;\n          return factor;\n        }\n\n        @Mutation()\n        mutationWithInputs(@Arg(\"inputs\", () => [SampleInput]) inputs: SampleInput[]): number {\n          // eslint-disable-next-line prefer-destructuring\n          mutationInputValue = inputs[0];\n          return inputs[0].factor;\n        }\n\n        @Mutation()\n        mutationWithTripleArrayInputs(\n          @Arg(\"inputs\", () => [[[SampleInput]]]) inputs: SampleInput[][][],\n        ): number {\n          mutationInputValue = inputs;\n          return inputs[0][0][0].factor;\n        }\n\n        @Mutation()\n        mutationWithOptionalArg(\n          @Arg(\"input\", { nullable: true }) input?: SampleNestedInput,\n        ): number {\n          mutationInputValue = typeof input;\n          return 0;\n        }\n\n        @FieldResolver()\n        fieldResolverField() {\n          return this.randomValueField;\n        }\n\n        @FieldResolver()\n        fieldResolverGetter() {\n          return this.randomValueGetter;\n        }\n\n        @FieldResolver({ complexity: 10 })\n        fieldResolverMethod() {\n          return this.getRandomValue();\n        }\n\n        @FieldResolver()\n        fieldResolverWithRoot(@Root() root: SampleObject) {\n          if (root.isTrue()) {\n            return root.instanceValue;\n          }\n\n          return -1.0;\n        }\n\n        @FieldResolver()\n        fieldResolverMethodWithArgs(@Root() _: SampleObject, @Arg(\"arg\") arg: number): number {\n          return arg;\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n    });\n\n    it(\"should build the schema without errors\", () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should return value from object getter resolver\", async () => {\n      const query = `query {\n        sampleQuery {\n          getterField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const getterFieldResult = result.data!.sampleQuery.getterField;\n      expect(getterFieldResult).toBeGreaterThanOrEqual(0);\n      expect(getterFieldResult).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should return value from object method resolver\", async () => {\n      const query = `query {\n        sampleQuery {\n          methodField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const methodFieldResult = result.data!.sampleQuery.methodField;\n      expect(methodFieldResult).toBeGreaterThanOrEqual(0);\n      expect(methodFieldResult).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should return value from object async method resolver\", async () => {\n      const query = `query {\n        sampleQuery {\n          asyncMethodField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const asyncMethodFieldResult = result.data!.sampleQuery.asyncMethodField;\n      expect(asyncMethodFieldResult).toEqual(\"asyncMethodField\");\n    });\n\n    it(\"should return value from object method resolver with arg\", async () => {\n      const query = `query {\n        sampleQuery {\n          methodFieldWithArg(factor: 10)\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const methodFieldWithArgResult = result.data!.sampleQuery.methodFieldWithArg;\n      expect(methodFieldWithArgResult).toBeGreaterThanOrEqual(0);\n      expect(methodFieldWithArgResult).toBeLessThanOrEqual(10);\n    });\n\n    it(\"should return value from field resolver with field access\", async () => {\n      const query = `query {\n        sampleQuery {\n          fieldResolverField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const fieldResolverFieldResult = result.data!.sampleQuery.fieldResolverField;\n      expect(fieldResolverFieldResult).toBeGreaterThanOrEqual(0);\n      expect(fieldResolverFieldResult).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should return value from field resolver with getter access\", async () => {\n      const query = `query {\n        sampleQuery {\n          fieldResolverGetter\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const fieldResolverGetterResult = result.data!.sampleQuery.fieldResolverGetter;\n      expect(fieldResolverGetterResult).toBeGreaterThanOrEqual(0);\n      expect(fieldResolverGetterResult).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should return value from field resolver with method access\", async () => {\n      const query = `query {\n        sampleQuery {\n          fieldResolverMethod\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const fieldResolverMethodResult = result.data!.sampleQuery.fieldResolverMethod;\n      expect(fieldResolverMethodResult).toBeGreaterThanOrEqual(0);\n      expect(fieldResolverMethodResult).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should return value from field resolver arg\", async () => {\n      const value = 21.37;\n      const query = `query {\n        sampleQuery {\n          fieldResolverMethodWithArgs(arg: ${value})\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      const resultFieldData = result.data!.sampleQuery.fieldResolverMethodWithArgs;\n      expect(resultFieldData).toEqual(value);\n    });\n\n    it(\"should create new instances of object type for consecutive queries\", async () => {\n      const query = `query {\n        sampleQuery {\n          getterField\n        }\n      }`;\n\n      const result1: any = await graphql({ schema, source: query });\n      const result2: any = await graphql({ schema, source: query });\n\n      const getterFieldResult1 = result1.data!.sampleQuery.getterField;\n      const getterFieldResult2 = result2.data!.sampleQuery.getterField;\n      expect(getterFieldResult1).not.toEqual(getterFieldResult2);\n    });\n\n    it(\"shouldn't create new instance for object type if it's already an instance of its class\", async () => {\n      const query = /* graphql */ `\n        query {\n          sampleQuery {\n            getterField\n            methodField\n          }\n        }\n      `;\n\n      const result: any = await graphql({ schema, source: query });\n      const getterFieldValue = result.data!.sampleQuery.getterField;\n      const methodFieldValue = result.data!.sampleQuery.getterField;\n\n      expect(getterFieldValue).toEqual(methodFieldValue);\n      expect(sampleObjectConstructorCallCount).toBe(1);\n    });\n\n    it(\"should use the same instance of resolver class for consecutive queries\", async () => {\n      const query = `query {\n        sampleQuery {\n          fieldResolverField\n        }\n      }`;\n\n      const result1: any = await graphql({ schema, source: query });\n      const result2: any = await graphql({ schema, source: query });\n\n      const resolverFieldResult1 = result1.data!.sampleQuery.fieldResolverField;\n      const resolverFieldResult2 = result2.data!.sampleQuery.fieldResolverField;\n      expect(resolverFieldResult1).toEqual(resolverFieldResult2);\n    });\n\n    it(\"should create instance of args object\", async () => {\n      const mutation = `mutation {\n        mutationWithArgs(factor: 10)\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithArgs;\n\n      expect(result).toBeGreaterThanOrEqual(0);\n      expect(result).toBeLessThanOrEqual(10);\n    });\n\n    it(\"shouldn't create properties of nullable args\", async () => {\n      const mutation = `mutation {\n        mutationWithOptionalArgs(stringField: \"stringField\")\n      }`;\n\n      const { errors } = await graphql({ schema, source: mutation });\n\n      expect(errors).toBeUndefined();\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleOptionalArgs);\n      expect(mutationInputValue).not.toHaveProperty(\"optionalField\");\n    });\n\n    it(\"should create instance of input object\", async () => {\n      const mutation = `mutation {\n        mutationWithInput(input: { factor: 10 })\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithInput;\n\n      expect(result).toBeGreaterThanOrEqual(0);\n      expect(result).toBeLessThanOrEqual(10);\n    });\n\n    it(\"should create instances of nested input fields input objects without undefined\", async () => {\n      const mutation = `mutation {\n        mutationWithNestedInputs(input: {\n          nestedField: {\n            factor: 20\n          }\n          nestedArrayField: [{\n            factor: 30\n          }]\n        })\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithNestedInputs;\n\n      expect(result).toBeGreaterThanOrEqual(0);\n      expect(result).toBeLessThanOrEqual(1);\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleNestedInput);\n      expect(mutationInputValue.nestedField).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue.nestedArrayField[0]).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue).not.toHaveProperty(\"optionalNestedField\");\n    });\n\n    it(\"shouldn't create instances of nested input fields nullable input objects when null provided\", async () => {\n      const mutation = `mutation {\n        mutationWithNestedInputs(input: {\n          nestedField: {\n            factor: 20\n          }\n          nestedArrayField: [{\n            factor: 30\n          }]\n          optionalNestedField: null\n          nestedOptionalArrayField: [null, { factor: 40 }]\n        })\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      expect(mutationResult.errors).toBeUndefined();\n\n      const mutationWithNestedInputsData = mutationResult.data!.mutationWithNestedInputs;\n      expect(mutationWithNestedInputsData).toBeGreaterThanOrEqual(0);\n      expect(mutationWithNestedInputsData).toBeLessThanOrEqual(1);\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleNestedInput);\n      expect(mutationInputValue.nestedField).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue.nestedArrayField[0]).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue.optionalNestedField).toBeNull();\n      expect(mutationInputValue.nestedOptionalArrayField).toEqual([\n        null,\n        expect.any(classes.SampleInput),\n      ]);\n    });\n\n    it(\"should create instance of nested input field of args type object\", async () => {\n      const mutation = `mutation {\n        mutationWithNestedArgsInput(factor: 20, input: { factor: 30 })\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithNestedArgsInput;\n\n      expect(result).toEqual(20);\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue.instanceField).toBeGreaterThanOrEqual(0);\n      expect(mutationInputValue.instanceField).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should create instance of inputs array from arg\", async () => {\n      const mutation = `mutation {\n        mutationWithInputs(inputs: [{ factor: 30 }])\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithInputs;\n\n      expect(result).toEqual(30);\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleInput);\n      expect(mutationInputValue.instanceField).toBeGreaterThanOrEqual(0);\n      expect(mutationInputValue.instanceField).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should create instance of nested arrays input from arg\", async () => {\n      const mutation = `mutation {\n        mutationWithTripleArrayInputs(inputs: [[[{ factor: 30 }]]])\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      const result = mutationResult.data!.mutationWithTripleArrayInputs;\n      const nestedInput = mutationInputValue[0][0][0];\n\n      expect(mutationResult.errors).toBeUndefined();\n      expect(result).toEqual(30);\n      expect(mutationInputValue).toBeInstanceOf(Array);\n      expect(mutationInputValue).toHaveLength(1);\n      expect(mutationInputValue[0]).toBeInstanceOf(Array);\n      expect(mutationInputValue[0]).toHaveLength(1);\n      expect(mutationInputValue[0][0]).toBeInstanceOf(Array);\n      expect(mutationInputValue[0][0]).toHaveLength(1);\n      expect(nestedInput).toBeInstanceOf(classes.SampleInput);\n      expect(nestedInput.instanceField).toBeGreaterThanOrEqual(0);\n      expect(nestedInput.instanceField).toBeLessThanOrEqual(1);\n    });\n\n    it(\"should create instance of nested arrays input field\", async () => {\n      const mutation = `mutation {\n        mutationWithTripleNestedInputs(input: {\n          deeplyNestedInputArrayField: [[[{ factor: 30 }]]]\n        })\n      }`;\n\n      const mutationResult = await graphql({ schema, source: mutation });\n      expect(mutationResult.errors).toBeUndefined();\n\n      const result = mutationResult.data!.mutationWithTripleNestedInputs;\n      expect(result).toEqual(30);\n\n      expect(mutationInputValue).toBeInstanceOf(classes.SampleTripleNestedInput);\n      expect(mutationInputValue.deeplyNestedInputArrayField).toHaveLength(1);\n      expect(mutationInputValue.deeplyNestedInputArrayField[0]).toBeInstanceOf(Array);\n      expect(mutationInputValue.deeplyNestedInputArrayField[0]).toHaveLength(1);\n      expect(mutationInputValue.deeplyNestedInputArrayField[0][0]).toBeInstanceOf(Array);\n      expect(mutationInputValue.deeplyNestedInputArrayField[0][0]).toHaveLength(1);\n\n      const nestedInput = mutationInputValue.deeplyNestedInputArrayField[0][0][0];\n      expect(nestedInput).toBeInstanceOf(classes.SampleInput);\n      expect(nestedInput.instanceField).toBeGreaterThanOrEqual(0);\n      expect(nestedInput.instanceField).toBeLessThanOrEqual(1);\n    });\n\n    it(\"shouldn't create instance of an argument if the value is null or not provided\", async () => {\n      const mutation = `mutation {\n        mutationWithOptionalArg\n      }`;\n\n      const { data, errors } = await graphql({ schema, source: mutation });\n      expect(errors).toBeUndefined();\n      expect(data!.mutationWithOptionalArg).toBeDefined();\n      expect(mutationInputValue).toEqual(\"undefined\");\n    });\n\n    it(\"should create instance of root object when root type is provided\", async () => {\n      const query = `query {\n        sampleQuery {\n          fieldResolverWithRoot\n          getterField\n        }\n      }`;\n\n      const queryResult: any = await graphql({ schema, source: query });\n      const fieldResolverWithRootValue = queryResult.data!.sampleQuery.fieldResolverWithRoot;\n      const getterFieldValue = queryResult.data!.sampleQuery.getterField;\n\n      expect(fieldResolverWithRootValue).toBeGreaterThanOrEqual(0);\n      expect(fieldResolverWithRootValue).toBeLessThanOrEqual(1);\n      expect(fieldResolverWithRootValue).toEqual(getterFieldValue);\n    });\n\n    it(\"should reuse data from instance of root object\", async () => {\n      const query = `query {\n        notInstanceQuery {\n          fieldResolverWithRoot\n          getterField\n        }\n      }`;\n\n      const queryResult: any = await graphql({ schema, source: query });\n      const fieldResolverWithRootValue = queryResult.data!.notInstanceQuery.fieldResolverWithRoot;\n      const getterFieldValue = queryResult.data!.notInstanceQuery.getterField;\n\n      expect(fieldResolverWithRootValue).toBeGreaterThanOrEqual(0);\n      expect(fieldResolverWithRootValue).toBeLessThanOrEqual(1);\n      expect(fieldResolverWithRootValue).not.toEqual(getterFieldValue);\n    });\n\n    it(\"should inject root and context object to resolver\", async () => {\n      const query = `query {\n        queryWithRootContextAndInfo\n      }`;\n      const root = { isRoot: true };\n      const context = { isContext: true };\n\n      await graphql({ schema, source: query, rootValue: root, contextValue: context });\n\n      expect(queryRoot).toEqual(root);\n      expect(queryContext).toEqual(context);\n      expect(queryInfo).toBeDefined();\n      expect(queryInfo.fieldName).toEqual(\"queryWithRootContextAndInfo\");\n    });\n\n    it(\"should inject parts of root and context objects to resolver\", async () => {\n      const query = `query {\n        queryWithPartialRootAndContext\n      }`;\n      const root = { rootField: 2 };\n      const context = { contextField: \"present\" };\n\n      await graphql({ schema, source: query, rootValue: root, contextValue: context });\n\n      expect(queryRoot).toEqual(2);\n      expect(queryContext).toEqual(\"present\");\n    });\n\n    it(\"should inject resolver data to custom arg decorator resolver and return its value\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryWithCustomDecorators\n        }\n      `;\n      const root = { rootField: 2 };\n      const context = { contextField: \"present\" };\n\n      await graphql({ schema, source: query, rootValue: root, contextValue: context });\n\n      expect(queryFirstCustom.root).toEqual(root);\n      expect(queryFirstCustom.context).toEqual(context);\n      expect(queryFirstCustom.info).toBeDefined();\n      expect(querySecondCustom).toEqual(\"secondCustom\");\n      expect(queryThirdCustom).toEqual(\"Default\");\n    });\n\n    it(\"should allow custom arg decorators to create args\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryWithCustomDecorators(thirdCustom: \"Overridden\")\n        }\n      `;\n      const root = { rootField: 2 };\n      const context = { contextField: \"present\" };\n\n      await graphql({ schema, source: query, rootValue: root, contextValue: context });\n\n      expect(queryFirstCustom.root).toEqual(root);\n      expect(queryFirstCustom.context).toEqual(context);\n      expect(queryFirstCustom.info).toBeDefined();\n      expect(querySecondCustom).toEqual(\"secondCustom\");\n      expect(queryThirdCustom).toEqual(\"Overridden\");\n    });\n\n    it(\"should allow for overwriting descriptor value in custom decorator\", async () => {\n      const query = /* graphql */ `\n        query {\n          queryWithCustomDescriptorDecorator\n        }\n      `;\n\n      const { data } = await graphql({ schema, source: query });\n\n      expect(descriptorEvaluated).toBe(true);\n      expect(data!.queryWithCustomDescriptorDecorator).toBe(true);\n    });\n  });\n\n  describe(\"buildSchema\", () => {\n    it(\"should emit only things from provided `resolvers` property\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleObject {\n          return { sampleField: \"sampleField\" };\n        }\n      }\n      @ObjectType()\n      class OmittedObject {\n        @Field()\n        omittedField!: string;\n      }\n      @Resolver()\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class OmittedResolver {\n        @Query()\n        omittedQuery(): OmittedObject {\n          return { omittedField: \"omittedField\" };\n        }\n      }\n\n      const { queryType, schemaIntrospection } = await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n      const objectTypes = schemaIntrospection.types.filter(\n        type =>\n          type.kind === \"OBJECT\" &&\n          !type.name.startsWith(\"__\") &&\n          ![\"Query\", \"Mutation\", \"Subscription\"].includes(type.name),\n      );\n\n      expect(queryType.fields).toHaveLength(1);\n      expect(queryType.fields[0].name).toEqual(\"sampleQuery\");\n      expect(objectTypes).toHaveLength(1);\n      expect(objectTypes[0].name).toEqual(\"SampleObject\");\n    });\n\n    it(\"should build the schema synchronously\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleFieldSync!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuerySync(): SampleObject {\n          return { sampleFieldSync: \"sampleFieldSync\" };\n        }\n      }\n\n      const schema = buildSchemaSync({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n      const query = `\n        query {\n          sampleQuerySync {\n            sampleFieldSync\n          }\n        }\n      `;\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data.sampleQuerySync.sampleFieldSync).toEqual(\"sampleFieldSync\");\n    });\n\n    it(\"should generate the schema when schema is incorrect but `skipCheck` is set to true\", async () => {\n      getMetadataStorage().clear();\n\n      @Resolver()\n      class SampleResolver {\n        @Mutation()\n        sampleMutation(): string {\n          return \"sampleMutation\";\n        }\n      }\n\n      const schema = await buildSchema({\n        resolvers: [SampleResolver],\n        skipCheck: true,\n      });\n\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should throw errors when no resolvers provided\", async () => {\n      getMetadataStorage().clear();\n\n      const error = await expectToThrow(() => buildSchema({ resolvers: [] as any }));\n\n      expect(error.message).toContain(\"Empty\");\n      expect(error.message).toContain(\"resolvers\");\n    });\n  });\n\n  describe(\"Schemas leaks\", () => {\n    it(\"should not call field resolver if resolver class is not provided to `buildSchema`\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n\n        @Field()\n        resolvedField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleObject {\n          return { sampleField: \"sampleField\", resolvedField: \"resolvedField\" };\n        }\n      }\n      @Resolver(() => SampleObject)\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObjectResolver {\n        @FieldResolver()\n        resolvedField(): string {\n          return \"SampleObjectResolver resolvedField\";\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          sampleQuery {\n            sampleField\n            resolvedField\n          }\n        }\n      `;\n      const schema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.errors).toBeUndefined();\n      expect(result.data!.sampleQuery).toEqual({\n        sampleField: \"sampleField\",\n        resolvedField: \"resolvedField\",\n      });\n    });\n\n    it(\"should not emit field in schema if resolver class is not provided to `buildSchema`\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleObject {\n          return { sampleField: \"sampleField\" };\n        }\n      }\n      @Resolver(() => SampleObject)\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      class SampleObjectResolver {\n        @FieldResolver()\n        resolvedField(): string {\n          return \"SampleObjectResolver resolvedField\";\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n      });\n      const { schemaIntrospection } = schemaInfo;\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n\n      expect(sampleObjectType.fields).toHaveLength(1);\n      expect(sampleObjectType.fields[0].name).toEqual(\"sampleField\");\n    });\n\n    it(\"should emit field in schema if resolver class is not provided to `buildSchema` but is in inheritance chain\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n      }\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): SampleObject {\n          return { sampleField: \"sampleField\" };\n        }\n      }\n      function createResolver() {\n        @Resolver(() => SampleObject)\n        class SampleObjectResolver {\n          @FieldResolver()\n          resolvedField(): string {\n            return \"SampleObjectResolver resolvedField\";\n          }\n        }\n        return SampleObjectResolver;\n      }\n      class ChildResolver extends createResolver() {}\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver, ChildResolver],\n      });\n      const { schemaIntrospection } = schemaInfo;\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n\n      expect(sampleObjectType.fields).toHaveLength(2);\n    });\n\n    it(\"should not duplicate resolver params when buildSchema is called twice\", async () => {\n      getMetadataStorage().clear();\n\n      @Resolver()\n      class SampleResolver {\n        @Query(() => String)\n        greet(@Arg(\"name\") name: string, @Ctx() ctx: { prefix: string }): string {\n          return `${ctx.prefix} ${name}`;\n        }\n      }\n\n      const context = { prefix: \"hi\" };\n      const query = /* graphql */ `\n        query {\n          greet(name: \"world\")\n        }\n      `;\n\n      const schema1 = await buildSchema({ resolvers: [SampleResolver], validate: false });\n      const result1 = await graphql({\n        schema: schema1,\n        source: query,\n        contextValue: context,\n      });\n      expect(result1.errors).toBeUndefined();\n      expect(result1.data).toEqual({ greet: \"hi world\" });\n\n      const schema2 = await buildSchema({ resolvers: [SampleResolver], validate: false });\n      const result2 = await graphql({\n        schema: schema2,\n        source: query,\n        contextValue: context,\n      });\n      expect(result2.errors).toBeUndefined();\n      expect(result2.data).toEqual({ greet: \"hi world\" });\n    });\n  });\n\n  describe(\"Inheritance\", () => {\n    let schema: GraphQLSchema;\n    let schemaIntrospection: IntrospectionSchema;\n    let queryType: IntrospectionObjectType;\n    let mutationType: IntrospectionObjectType;\n    let subscriptionType: IntrospectionObjectType;\n    let self: any;\n    let childResolver: any;\n    let overrideResolver: any;\n\n    const pubSub = createPubSub();\n\n    beforeEach(() => {\n      self = null;\n    });\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        normalField!: string;\n      }\n\n      @ObjectType()\n      class DummyObject {\n        @Field()\n        normalField!: string;\n      }\n\n      function createResolver(name: string, objectType: ClassType) {\n        @Resolver(() => objectType)\n        class BaseResolver {\n          protected name = \"baseName\";\n\n          @Query({ name: `${name}Query` })\n          baseQuery(@Arg(\"arg\") _arg: boolean): boolean {\n            self = this;\n            return true;\n          }\n\n          @Mutation({ name: `${name}Mutation` })\n          baseMutation(@Arg(\"arg\") _arg: boolean): boolean {\n            self = this;\n            return true;\n          }\n\n          @Subscription({ topics: \"baseTopic\", name: `${name}Subscription` })\n          baseSubscription(@Arg(\"arg\") _arg: boolean): boolean {\n            self = this;\n            return true;\n          }\n\n          @Mutation(() => Boolean, { name: `${name}Trigger` })\n          async baseTrigger(): Promise<boolean> {\n            pubSub.publish(\"baseTopic\", null);\n            return true;\n          }\n\n          @FieldResolver()\n          resolverField(): string {\n            self = this;\n            return \"resolverField\";\n          }\n        }\n\n        return BaseResolver;\n      }\n\n      @Resolver()\n      class ChildResolver extends createResolver(\"prefix\", SampleObject) {\n        @Query()\n        childQuery(): boolean {\n          self = this;\n          return true;\n        }\n\n        @Query()\n        objectQuery(): SampleObject {\n          return { normalField: \"normalField\" };\n        }\n\n        @Mutation()\n        childMutation(): boolean {\n          self = this;\n          return true;\n        }\n\n        @Subscription({ topics: \"childTopic\", complexity: 4 })\n        childSubscription(): boolean {\n          self = this;\n          return true;\n        }\n\n        @Mutation(() => Boolean)\n        async childTrigger(): Promise<boolean> {\n          pubSub.publish(\"childTopic\", null);\n          return true;\n        }\n      }\n      childResolver = ChildResolver;\n\n      @Resolver()\n      class OverrideResolver extends createResolver(\"overridden\", DummyObject) {\n        @Query()\n        overriddenQuery(@Arg(\"overriddenArg\") _arg: boolean): string {\n          self = this;\n          return \"overriddenQuery\";\n        }\n\n        @Mutation({ name: \"overriddenMutation\" })\n        overriddenMutationHandler(@Arg(\"overriddenArg\") _arg: boolean): string {\n          self = this;\n          return \"overriddenMutationHandler\";\n        }\n      }\n      overrideResolver = OverrideResolver;\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [childResolver, overrideResolver],\n        pubSub,\n      });\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      queryType = schemaInfo.queryType;\n      mutationType = schemaInfo.mutationType!;\n      subscriptionType = schemaInfo.subscriptionType!;\n      schema = schemaInfo.schema;\n    });\n\n    it(\"should build schema correctly\", async () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should generate proper queries in schema\", async () => {\n      const queryNames = queryType.fields.map(it => it.name);\n\n      expect(queryNames).toContain(\"childQuery\");\n      expect(queryNames).toContain(\"objectQuery\");\n      expect(queryNames).toContain(\"prefixQuery\");\n      expect(queryNames).toContain(\"overriddenQuery\");\n    });\n\n    it(\"should generate proper mutations in schema\", async () => {\n      const mutationNames = mutationType.fields.map(it => it.name);\n\n      expect(mutationNames).toContain(\"childMutation\");\n      expect(mutationNames).toContain(\"childTrigger\");\n      expect(mutationNames).toContain(\"prefixMutation\");\n      expect(mutationNames).toContain(\"prefixTrigger\");\n      expect(mutationNames).toContain(\"overriddenTrigger\");\n      expect(mutationNames).toContain(\"overriddenMutation\");\n    });\n\n    it(\"should generate proper subscriptions in schema\", async () => {\n      const subscriptionNames = subscriptionType.fields.map(it => it.name);\n      const prefixSubscription = subscriptionType.fields.find(\n        it => it.name === \"prefixSubscription\",\n      )!;\n\n      expect(subscriptionNames).toContain(\"childSubscription\");\n      expect(subscriptionNames).toContain(\"prefixSubscription\");\n      expect(subscriptionNames).toContain(\"overriddenSubscription\");\n      expect(prefixSubscription.args).toHaveLength(1);\n    });\n\n    it(\"should generate proper object fields in schema\", async () => {\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.kind === TypeKind.OBJECT && type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n      const sampleObjectTypeFieldsNames = sampleObjectType.fields.map(it => it.name);\n\n      expect(sampleObjectType.fields).toHaveLength(2);\n      expect(sampleObjectTypeFieldsNames).toContain(\"normalField\");\n      expect(sampleObjectTypeFieldsNames).toContain(\"resolverField\");\n    });\n\n    it(\"should overwrite args in schema when handler has been overridden\", async () => {\n      const prefixQuery = queryType.fields.find(it => it.name === \"prefixQuery\")!;\n      const overriddenQuery = queryType.fields.find(it => it.name === \"overriddenQuery\")!;\n      const prefixMutation = mutationType.fields.find(it => it.name === \"prefixMutation\")!;\n      const overriddenMutation = mutationType.fields.find(it => it.name === \"overriddenMutation\")!;\n\n      expect(prefixQuery.args).toHaveLength(1);\n      expect(prefixQuery.args[0].name).toEqual(\"arg\");\n      expect(overriddenQuery.args).toHaveLength(1);\n      expect(overriddenQuery.args[0].name).toEqual(\"overriddenArg\");\n      expect(prefixMutation.args).toHaveLength(1);\n      expect(prefixMutation.args[0].name).toEqual(\"arg\");\n      expect(overriddenMutation.args).toHaveLength(1);\n      expect(overriddenMutation.args[0].name).toEqual(\"overriddenArg\");\n    });\n\n    it(\"should overwrite return type in schema when handler has been overridden\", async () => {\n      const prefixQuery = queryType.fields.find(it => it.name === \"prefixQuery\")!;\n      const overriddenQuery = queryType.fields.find(it => it.name === \"overriddenQuery\")!;\n      const prefixMutation = mutationType.fields.find(it => it.name === \"prefixMutation\")!;\n      const overriddenMutation = mutationType.fields.find(it => it.name === \"overriddenMutation\")!;\n      const prefixQueryType = getInnerTypeOfNonNullableType(prefixQuery);\n      const overriddenQueryType = getInnerTypeOfNonNullableType(overriddenQuery);\n      const prefixMutationType = getInnerTypeOfNonNullableType(prefixMutation);\n      const overriddenMutationType = getInnerTypeOfNonNullableType(overriddenMutation);\n\n      expect(prefixQueryType.kind).toEqual(TypeKind.SCALAR);\n      expect(prefixQueryType.name).toEqual(\"Boolean\");\n      expect(overriddenQueryType.kind).toEqual(TypeKind.SCALAR);\n      expect(overriddenQueryType.name).toEqual(\"String\");\n      expect(prefixMutationType.kind).toEqual(TypeKind.SCALAR);\n      expect(prefixMutationType.name).toEqual(\"Boolean\");\n      expect(overriddenMutationType.kind).toEqual(TypeKind.SCALAR);\n      expect(overriddenMutationType.name).toEqual(\"String\");\n    });\n\n    it(\"should correctly call query handler from base resolver class\", async () => {\n      const query = `query {\n        prefixQuery(arg: true)\n      }`;\n\n      const { data } = await graphql({ schema, source: query });\n\n      expect(data!.prefixQuery).toEqual(true);\n      expect(self.constructor).toEqual(childResolver);\n    });\n\n    it(\"should correctly call mutation handler from base resolver class\", async () => {\n      const mutation = `mutation {\n        prefixMutation(arg: true)\n      }`;\n\n      const { data } = await graphql({ schema, source: mutation });\n\n      expect(data!.prefixMutation).toEqual(true);\n      expect(self.constructor).toEqual(childResolver);\n    });\n\n    it(\"should correctly call query handler from child resolver class\", async () => {\n      const query = `query {\n        childQuery\n      }`;\n\n      const { data } = await graphql({ schema, source: query });\n\n      expect(data!.childQuery).toEqual(true);\n      expect(self.constructor).toEqual(childResolver);\n    });\n\n    it(\"should correctly call mutation handler from child resolver class\", async () => {\n      const mutation = `mutation {\n        childMutation\n      }`;\n\n      const { data } = await graphql({ schema, source: mutation });\n\n      expect(data!.childMutation).toEqual(true);\n      expect(self.constructor).toEqual(childResolver);\n    });\n\n    it(\"should correctly call field resolver handler from base resolver class\", async () => {\n      const query = `query {\n        objectQuery {\n          resolverField\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data!.objectQuery.resolverField).toEqual(\"resolverField\");\n      expect(self.constructor).toEqual(childResolver);\n    });\n\n    it(\"should correctly call overridden query handler from child resolver class\", async () => {\n      const query = `query {\n        overriddenQuery(overriddenArg: true)\n      }`;\n\n      const { data } = await graphql({ schema, source: query });\n\n      expect(data!.overriddenQuery).toEqual(\"overriddenQuery\");\n      expect(self.constructor).toEqual(overrideResolver);\n    });\n\n    it(\"should correctly call overridden mutation handler from child resolver class\", async () => {\n      const mutation = `mutation {\n        overriddenMutation(overriddenArg: true)\n      }`;\n\n      const { data } = await graphql({ schema, source: mutation });\n\n      expect(data!.overriddenMutation).toEqual(\"overriddenMutationHandler\");\n      expect(self.constructor).toEqual(overrideResolver);\n    });\n\n    it(\"should have access to inherited properties from base resolver class\", async () => {\n      const query = `query {\n        childQuery\n      }`;\n\n      await graphql({ schema, source: query });\n\n      expect(self.name).toEqual(\"baseName\");\n    });\n\n    it(\"should get child class instance when calling base resolver handler\", async () => {\n      const query = `query {\n        prefixQuery(arg: true)\n      }`;\n\n      await graphql({ schema, source: query });\n\n      expect(self).toBeInstanceOf(childResolver);\n    });\n\n    it(\"should allow duplicate fieldResolver methods with different schema names for inherited resolvers\", async () => {\n      getMetadataStorage().clear();\n      const INHERITED_DYNAMIC_FIELD_NAME_1 = \"dynamicallyNamedMethod1\";\n      const INHERITED_DYNAMIC_FIELD_NAME_2 = \"dynamicallyNamedMethod2\";\n\n      const withDynamicallyNamedFieldResolver = (\n        classType: ClassType,\n        BaseResolverClass: ClassType,\n        name: string,\n      ) => {\n        @Resolver(() => classType)\n        class DynamicallyNamedFieldResolver extends BaseResolverClass {\n          @FieldResolver({ name })\n          dynamicallyNamedField(): boolean {\n            return true;\n          }\n        }\n        return DynamicallyNamedFieldResolver;\n      };\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n      }\n\n      @Resolver()\n      class SampleResolver {\n        @Query(() => SampleObject)\n        sampleObject(): SampleObject {\n          return { sampleField: \"sampleText\" };\n        }\n      }\n\n      const DynamicallyNamedFieldResolver1 = withDynamicallyNamedFieldResolver(\n        SampleObject,\n        SampleResolver,\n        INHERITED_DYNAMIC_FIELD_NAME_1,\n      );\n      const DynamicallyNamedFieldResolver2 = withDynamicallyNamedFieldResolver(\n        SampleObject,\n        DynamicallyNamedFieldResolver1,\n        INHERITED_DYNAMIC_FIELD_NAME_2,\n      );\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [DynamicallyNamedFieldResolver2],\n      });\n      schemaIntrospection = schemaInfo.schemaIntrospection;\n      const sampleObjectType = schemaIntrospection.types.find(\n        type => type.name === \"SampleObject\",\n      ) as IntrospectionObjectType;\n\n      const dynamicField1 = sampleObjectType.fields.find(\n        field => field.name === INHERITED_DYNAMIC_FIELD_NAME_1,\n      )!;\n\n      const dynamicField2 = sampleObjectType.fields.find(\n        field => field.name === INHERITED_DYNAMIC_FIELD_NAME_2,\n      )!;\n\n      expect(dynamicField1).toBeDefined();\n      expect(dynamicField2).toBeDefined();\n    });\n\n    it(\"should resolve independent factory-created field resolvers with different schema names correctly\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class FactoryUser {\n        @Field()\n        name!: string;\n      }\n\n      function createFieldResolver(fieldName: string, returnValue: string) {\n        @Resolver(() => FactoryUser)\n        class DynamicFieldResolver {\n          @FieldResolver(() => [String], { name: fieldName })\n          getItems(): string[] {\n            return [returnValue];\n          }\n        }\n        return DynamicFieldResolver;\n      }\n\n      const FollowersResolver = createFieldResolver(\"followers\", \"follower1\");\n      const FollowingResolver = createFieldResolver(\"following\", \"following1\");\n\n      @Resolver()\n      class FactoryUserResolver {\n        @Query(() => FactoryUser)\n        factoryUser(): FactoryUser {\n          return { name: \"TestUser\" } as FactoryUser;\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [FactoryUserResolver, FollowersResolver, FollowingResolver],\n      });\n      const { schema: factorySchema, schemaIntrospection: factorySchemaIntrospection } = schemaInfo;\n\n      // Introspection check\n      const factoryUserType = factorySchemaIntrospection.types.find(\n        type => type.name === \"FactoryUser\",\n      ) as IntrospectionObjectType;\n      expect(factoryUserType.fields.find(f => f.name === \"followers\")).toBeDefined();\n      expect(factoryUserType.fields.find(f => f.name === \"following\")).toBeDefined();\n\n      // Runtime execution check\n      const query = `{ factoryUser { name followers following } }`;\n      const result = await graphql({ schema: factorySchema, source: query });\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toEqual({\n        factoryUser: {\n          name: \"TestUser\",\n          followers: [\"follower1\"],\n          following: [\"following1\"],\n        },\n      });\n    });\n  });\n\n  describe(\"Shared generic resolver\", () => {\n    beforeEach(async () => {\n      getMetadataStorage().clear();\n    });\n\n    it(\"should handle arguments correctly on multiple buildSchema runs\", async () => {\n      @ObjectType()\n      class TestResponse {\n        @Field()\n        data!: string;\n      }\n\n      @ArgsType()\n      class TestArgs {\n        @Field(() => Int, { defaultValue: 0 })\n        testField!: number;\n      }\n\n      function makeResolverClass() {\n        @Resolver(() => TestResponse)\n        abstract class TestResolver {\n          @Query(() => TestResponse)\n          async exampleQuery(@Args() args: TestArgs): Promise<TestResponse> {\n            return {\n              data: `resolver ${args.testField}`,\n            };\n          }\n        }\n\n        return TestResolver;\n      }\n\n      @Resolver()\n      class TestResolver extends makeResolverClass() {}\n\n      const fistSchemaInfo = await getSchemaInfo({\n        resolvers: [TestResolver],\n      });\n\n      expect(fistSchemaInfo.queryType.fields).toHaveLength(1);\n      expect(fistSchemaInfo.queryType.fields[0].args).toHaveLength(1);\n\n      const secondSchemaInfo = await getSchemaInfo({\n        resolvers: [TestResolver],\n      });\n\n      expect(secondSchemaInfo.queryType.fields).toHaveLength(1);\n      expect(secondSchemaInfo.queryType.fields[0].args).toHaveLength(1);\n    });\n\n    it(\"should handle field resolvers correctly on multiple buildSchema runs\", async () => {\n      @ObjectType()\n      class TestResponse {\n        @Field()\n        data!: string;\n      }\n\n      @ArgsType()\n      class TestArgs {\n        @Field(() => Int, { defaultValue: 0 })\n        testField!: number;\n      }\n\n      function makeResolverClass() {\n        @Resolver(() => TestResponse)\n        abstract class TestResolver {\n          @Query(() => TestResponse)\n          async exampleQuery(@Args() args: TestArgs): Promise<TestResponse> {\n            return {\n              data: `resolver ${args.testField}`,\n            };\n          }\n        }\n\n        return TestResolver;\n      }\n\n      @Resolver(() => TestResponse)\n      class TestResolver extends makeResolverClass() {\n        @FieldResolver(() => Boolean, { nullable: false })\n        public async exampleFieldResolver(): Promise<boolean> {\n          return true;\n        }\n      }\n\n      @ObjectType()\n      class OtherTestResponse {\n        @Field()\n        data!: string;\n      }\n\n      @ArgsType()\n      class OtherTestArgs {\n        @Field(() => Int, { defaultValue: 0 })\n        testField!: number;\n      }\n\n      function makeOtherResolverClass() {\n        @Resolver(() => OtherTestResponse)\n        abstract class OtherTestResolver {\n          @Query(() => OtherTestResponse)\n          async exampleQuery(@Args() args: OtherTestArgs): Promise<OtherTestResponse> {\n            return {\n              data: `resolver ${args.testField}`,\n            };\n          }\n        }\n\n        return OtherTestResolver;\n      }\n\n      @Resolver(() => OtherTestResponse)\n      class OtherTestResolver extends makeOtherResolverClass() {\n        @FieldResolver(() => Boolean, { nullable: false })\n        public async exampleFieldResolver(): Promise<boolean> {\n          return true;\n        }\n      }\n\n      const fistSchemaInfo = await getSchemaInfo({\n        resolvers: [TestResolver],\n      });\n\n      const hasFoundFieldResolverInSchema = fistSchemaInfo.schemaIntrospection.types.some(\n        type =>\n          type.kind === \"OBJECT\" &&\n          type.name === \"TestResponse\" &&\n          type.fields?.some(field => field.name === \"exampleFieldResolver\"),\n      );\n      expect(hasFoundFieldResolverInSchema).toBeTruthy();\n\n      const secondSchemaInfo = await getSchemaInfo({\n        resolvers: [OtherTestResolver],\n      });\n\n      const hasFoundFieldResolverInOtherSchema = secondSchemaInfo.schemaIntrospection.types.some(\n        type =>\n          type.kind === \"OBJECT\" &&\n          type.name === \"OtherTestResponse\" &&\n          type.fields?.some(field => field.name === \"exampleFieldResolver\"),\n      );\n      expect(hasFoundFieldResolverInOtherSchema).toBeTruthy();\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/scalars.ts",
    "content": "import \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport {\n  Arg,\n  Field,\n  Float,\n  GraphQLISODateTime,\n  GraphQLTimestamp,\n  ID,\n  Int,\n  ObjectType,\n  Query,\n  Resolver,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { CustomScalar, CustomType, ObjectScalar } from \"../helpers/customScalar\";\nimport { getSampleObjectFieldType } from \"../helpers/getSampleObjectFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Scalars\", () => {\n  let schemaIntrospection: IntrospectionSchema;\n  let sampleObject: IntrospectionObjectType;\n  let schema: GraphQLSchema;\n  let argScalar: string | undefined;\n\n  beforeEach(() => {\n    argScalar = undefined;\n  });\n\n  beforeAll(async () => {\n    // create sample definitions\n\n    @ObjectType()\n    class SampleObject {\n      @Field(() => ID)\n      idField: any;\n\n      @Field()\n      implicitFloatField!: number;\n\n      @Field(() => Float)\n      explicitFloatField: any;\n\n      @Field(() => Int)\n      intField: any;\n\n      @Field()\n      implicitStringField!: string;\n\n      @Field(() => String)\n      explicitStringField: any;\n\n      @Field()\n      implicitBooleanField!: boolean;\n\n      @Field(() => Boolean)\n      explicitBooleanField: any;\n\n      @Field()\n      implicitDateField!: Date;\n\n      @Field(() => Date)\n      explicitDateField: any;\n\n      @Field(() => GraphQLISODateTime)\n      ISODateField: any;\n\n      @Field(() => GraphQLTimestamp)\n      timestampField: any;\n\n      @Field(() => CustomScalar)\n      customScalarField: any;\n    }\n\n    @Resolver(() => SampleObject)\n    class SampleResolver {\n      @Query()\n      mainQuery(): SampleObject {\n        return {} as any;\n      }\n\n      @Query(() => CustomScalar)\n      returnScalar(): string {\n        return \"returnScalar\";\n      }\n\n      @Query(() => Boolean)\n      argScalar(@Arg(\"scalar\", () => CustomScalar) scalar: any): any {\n        argScalar = scalar;\n        return true;\n      }\n\n      @Query(() => Boolean)\n      objectArgScalar(@Arg(\"scalar\", () => ObjectScalar) scalar: any): any {\n        argScalar = scalar;\n        return true;\n      }\n\n      @Query(() => Date)\n      returnDate(): any {\n        return new Date();\n      }\n\n      @Query()\n      argDate(@Arg(\"date\", () => Date) _date: any): boolean {\n        return true;\n      }\n    }\n\n    // get builded schema info from retrospection\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [SampleResolver],\n    });\n\n    schema = schemaInfo.schema;\n    schemaIntrospection = schemaInfo.schemaIntrospection;\n    sampleObject = schemaIntrospection.types.find(\n      field => field.name === \"SampleObject\",\n    ) as IntrospectionObjectType;\n  });\n\n  describe(\"Schema\", () => {\n    function getFieldType(name: string) {\n      const field = sampleObject.fields.find(it => it.name === name)!;\n      const fieldType = (field.type as IntrospectionNonNullTypeRef)\n        .ofType as IntrospectionNamedTypeRef;\n      return fieldType;\n    }\n\n    it(\"should generate ID scalar field type\", async () => {\n      const idFieldType = getFieldType(\"idField\");\n\n      expect(idFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(idFieldType.name).toEqual(\"ID\");\n    });\n\n    it(\"should generate Float scalar field type\", async () => {\n      const explicitFloatFieldType = getFieldType(\"explicitFloatField\");\n\n      expect(explicitFloatFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(explicitFloatFieldType.name).toEqual(\"Float\");\n    });\n\n    it(\"should generate Float scalar field type when prop type is number\", async () => {\n      const implicitFloatFieldType = getFieldType(\"implicitFloatField\");\n\n      expect(implicitFloatFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(implicitFloatFieldType.name).toEqual(\"Float\");\n    });\n\n    it(\"should generate Int scalar field type\", async () => {\n      const intFieldType = getFieldType(\"intField\");\n\n      expect(intFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(intFieldType.name).toEqual(\"Int\");\n    });\n\n    it(\"should generate String scalar field type\", async () => {\n      const explicitStringFieldType = getFieldType(\"explicitStringField\");\n\n      expect(explicitStringFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(explicitStringFieldType.name).toEqual(\"String\");\n    });\n\n    it(\"should generate String scalar field type when prop type is string\", async () => {\n      const implicitStringFieldType = getFieldType(\"implicitStringField\");\n\n      expect(implicitStringFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(implicitStringFieldType.name).toEqual(\"String\");\n    });\n\n    it(\"should generate Date scalar field type\", async () => {\n      const explicitDateFieldType = getFieldType(\"explicitDateField\");\n\n      expect(explicitDateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(explicitDateFieldType.name).toEqual(\"DateTimeISO\");\n    });\n\n    it(\"should generate Date scalar field type when prop type is Date\", async () => {\n      const implicitStringFieldType = getFieldType(\"implicitDateField\");\n\n      expect(implicitStringFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(implicitStringFieldType.name).toEqual(\"DateTimeISO\");\n    });\n\n    it(\"should generate ISODate scalar field type\", async () => {\n      const ISODateFieldType = getFieldType(\"ISODateField\");\n\n      expect(ISODateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(ISODateFieldType.name).toEqual(\"DateTimeISO\");\n    });\n\n    it(\"should generate Timestamp scalar field type\", async () => {\n      const timestampFieldType = getFieldType(\"timestampField\");\n\n      expect(timestampFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(timestampFieldType.name).toEqual(\"Timestamp\");\n    });\n\n    it(\"should generate custom scalar field type\", async () => {\n      const customScalarFieldType = getFieldType(\"customScalarField\");\n\n      expect(customScalarFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(customScalarFieldType.name).toEqual(\"Custom\");\n    });\n  });\n\n  describe(\"Custom scalar\", () => {\n    it(\"should properly serialize data\", async () => {\n      const query = `query {\n        returnScalar\n      }`;\n      const result: any = await graphql({ schema, source: query });\n      const { returnScalar } = result.data!;\n\n      expect(returnScalar).toEqual(\"TypeGraphQL serialize\");\n    });\n\n    it(\"should properly parse args\", async () => {\n      const query = `query {\n        argScalar(scalar: \"test\")\n      }`;\n      await graphql({ schema, source: query });\n\n      expect(argScalar!).toEqual(\"TypeGraphQL parseLiteral\");\n    });\n\n    it(\"should properly parse scalar object\", async () => {\n      const query = `query {\n        objectArgScalar(scalar: \"test\")\n      }`;\n      await graphql({ schema, source: query });\n\n      expect(argScalar!).toEqual({ value: \"TypeGraphQL parseLiteral\" });\n    });\n  });\n\n  describe(\"Settings\", () => {\n    let sampleResolver: any;\n\n    beforeAll(() => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field(() => Date)\n        dateField: any;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        mainQuery(): SampleObject {\n          return {} as any;\n        }\n      }\n      sampleResolver = SampleResolver;\n    });\n\n    it(\"should generate iso date scalar field type by default\", async () => {\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [sampleResolver],\n      });\n      const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)(\"dateField\");\n\n      expect(dateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(dateFieldType.name).toEqual(\"DateTimeISO\");\n    });\n\n    it(\"should generate DateTime scalar field type when scalarsMap is using GraphQLISODateTime\", async () => {\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [sampleResolver],\n        scalarsMap: [{ type: Date, scalar: GraphQLISODateTime }],\n      });\n      const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)(\"dateField\");\n\n      expect(dateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(dateFieldType.name).toEqual(\"DateTimeISO\");\n    });\n\n    it(\"should generate Timestamp scalar field type when scalarsMap is using GraphQLTimestamp\", async () => {\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [sampleResolver],\n        scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],\n      });\n      const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)(\"dateField\");\n\n      expect(dateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(dateFieldType.name).toEqual(\"Timestamp\");\n    });\n\n    it(\"should generate custom scalar field type when defined in scalarMap\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        customField!: CustomType;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        mainQuery(): SampleObject {\n          return {} as any;\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        scalarsMap: [{ type: CustomType, scalar: CustomScalar }],\n      });\n      const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)(\"customField\");\n\n      expect(dateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(dateFieldType.name).toEqual(\"Custom\");\n    });\n\n    it(\"should generate custom scalar field type when overwriteDate in scalarMap\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field(() => Date)\n        dateField: any;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        mainQuery(): SampleObject {\n          return {} as any;\n        }\n      }\n\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        scalarsMap: [{ type: Date, scalar: CustomScalar }],\n      });\n      const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)(\"dateField\");\n\n      expect(dateFieldType.kind).toEqual(TypeKind.SCALAR);\n      expect(dateFieldType.name).toEqual(\"Custom\");\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/simple-resolvers.ts",
    "content": "import \"reflect-metadata\";\nimport { type GraphQLSchema, execute } from \"graphql\";\nimport gql from \"graphql-tag\";\nimport { Field, type MiddlewareFn, ObjectType, Query, Resolver, buildSchema } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"Simple resolvers\", () => {\n  let schema: GraphQLSchema;\n  let middlewareLogs: string[] = [];\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    const testMiddleware: MiddlewareFn = async (_, next) => {\n      middlewareLogs.push(\"middleware executed\");\n      return next();\n    };\n\n    @ObjectType()\n    class NormalObject {\n      @Field()\n      normalField!: string;\n    }\n    @ObjectType()\n    class ObjectWithSimpleField {\n      @Field({ simple: true })\n      simpleField!: string;\n    }\n    @ObjectType({ simpleResolvers: true })\n    class SimpleObject {\n      @Field()\n      simpleField!: string;\n    }\n    @ObjectType({ simpleResolvers: true })\n    class SimpleObjectWithNormalField {\n      @Field({ simple: false })\n      normalField!: string;\n    }\n\n    @Resolver()\n    class TestResolver {\n      @Query()\n      normalObjectQuery(): NormalObject {\n        return { normalField: \"normalField\" };\n      }\n\n      @Query()\n      objectWithSimpleFieldQuery(): ObjectWithSimpleField {\n        return { simpleField: \"simpleField\" };\n      }\n\n      @Query()\n      simpleObjectQuery(): SimpleObject {\n        return { simpleField: \"simpleField\" };\n      }\n\n      @Query()\n      simpleObjectWithNormalFieldQuery(): SimpleObjectWithNormalField {\n        return { normalField: \"normalField\" };\n      }\n    }\n\n    schema = await buildSchema({\n      resolvers: [TestResolver],\n      globalMiddlewares: [testMiddleware],\n    });\n  });\n\n  beforeEach(() => {\n    middlewareLogs = [];\n  });\n\n  it(\"should execute middlewares for field resolvers for normal object\", async () => {\n    const document = gql`\n      query {\n        normalObjectQuery {\n          normalField\n        }\n      }\n    `;\n\n    await execute({ schema, document });\n\n    expect(middlewareLogs).toHaveLength(2);\n  });\n\n  it(\"shouldn't execute middlewares for simple field resolvers\", async () => {\n    const document = gql`\n      query {\n        objectWithSimpleFieldQuery {\n          simpleField\n        }\n      }\n    `;\n\n    await execute({ schema, document });\n\n    expect(middlewareLogs).toHaveLength(1);\n  });\n\n  it(\"shouldn't execute middlewares for field resolvers of simple objects\", async () => {\n    const document = gql`\n      query {\n        simpleObjectQuery {\n          simpleField\n        }\n      }\n    `;\n\n    await execute({ schema, document });\n\n    expect(middlewareLogs).toHaveLength(1);\n  });\n\n  it(\"should execute middlewares for not simple field resolvers of simple objects\", async () => {\n    const document = gql`\n      query {\n        simpleObjectWithNormalFieldQuery {\n          normalField\n        }\n      }\n    `;\n\n    await execute({ schema, document });\n\n    expect(middlewareLogs).toHaveLength(2);\n  });\n});\n"
  },
  {
    "path": "tests/functional/subscriptions.ts",
    "content": "import \"reflect-metadata\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport {\n  type DocumentNode,\n  type ExecutionResult,\n  type GraphQLSchema,\n  type IntrospectionObjectType,\n  TypeKind,\n  execute,\n  subscribe,\n} from \"graphql\";\nimport gql from \"graphql-tag\";\nimport {\n  Arg,\n  Authorized,\n  Field,\n  Float,\n  Int,\n  MissingPubSubError,\n  MissingSubscriptionTopicsError,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  Root,\n  Subscription,\n  buildSchema,\n} from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { expectToThrow } from \"../helpers/expectToThrow\";\nimport { getInnerTypeOfNonNullableType, getItemTypeOfList } from \"../helpers/getInnerFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\nimport { sleep } from \"../helpers/sleep\";\n\ndescribe(\"Subscriptions\", () => {\n  const pubSub = createPubSub();\n\n  describe(\"Schema\", () => {\n    let schema: GraphQLSchema;\n    let subscriptionType: IntrospectionObjectType;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field()\n        sampleField!: string;\n      }\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): boolean {\n          return true;\n        }\n\n        @Subscription({ topics: \"STH\" })\n        sampleSubscription(): boolean {\n          return true;\n        }\n\n        @Subscription({ topics: \"STH\" })\n        subscriptionWithArgs(\n          @Arg(\"stringArg\") _stringArg: string,\n          @Arg(\"booleanArg\") _booleanArg: boolean,\n        ): boolean {\n          return true;\n        }\n\n        @Subscription(() => [SampleObject], { topics: \"STH\" })\n        subscriptionWithExplicitType(): any {\n          return true;\n        }\n      }\n      const schemaInfo = await getSchemaInfo({\n        resolvers: [SampleResolver],\n        pubSub,\n      });\n      schema = schemaInfo.schema;\n      subscriptionType = schemaInfo.subscriptionType!;\n    });\n\n    it(\"should build schema without errors\", () => {\n      expect(schema).toBeDefined();\n    });\n\n    it(\"should correctly generate simple subscription type\", () => {\n      const sampleSubscription = subscriptionType.fields.find(\n        field => field.name === \"sampleSubscription\",\n      )!;\n      const sampleSubscriptionType = getInnerTypeOfNonNullableType(sampleSubscription);\n\n      expect(sampleSubscription).toBeDefined();\n      expect(sampleSubscription.args).toHaveLength(0);\n      expect(sampleSubscriptionType.kind).toEqual(TypeKind.SCALAR);\n      expect(sampleSubscriptionType.name).toEqual(\"Boolean\");\n    });\n\n    it(\"should correctly generate type of subscription with args\", () => {\n      const subscriptionWithArgs = subscriptionType.fields.find(\n        field => field.name === \"subscriptionWithArgs\",\n      )!;\n      const subscriptionWithArgsType = getInnerTypeOfNonNullableType(subscriptionWithArgs);\n\n      expect(subscriptionWithArgs).toBeDefined();\n      expect(subscriptionWithArgs.args).toHaveLength(2);\n      expect(subscriptionWithArgsType.kind).toEqual(TypeKind.SCALAR);\n      expect(subscriptionWithArgsType.name).toEqual(\"Boolean\");\n    });\n\n    it(\"should correctly generate type of subscription with explicit type\", () => {\n      const subscriptionWithExplicitType = subscriptionType.fields.find(\n        field => field.name === \"subscriptionWithExplicitType\",\n      )!;\n      const innerType = getInnerTypeOfNonNullableType(subscriptionWithExplicitType);\n      const itemType = getItemTypeOfList(subscriptionWithExplicitType);\n\n      expect(subscriptionWithExplicitType).toBeDefined();\n      expect(subscriptionWithExplicitType.args).toHaveLength(0);\n      expect(innerType.kind).toEqual(TypeKind.LIST);\n      expect(itemType.kind).toEqual(TypeKind.OBJECT);\n      expect(itemType.name).toEqual(\"SampleObject\");\n    });\n  });\n\n  describe(\"Functional\", () => {\n    let schema: GraphQLSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field(() => Float)\n        value!: number;\n      }\n\n      const SAMPLE_TOPIC = \"SAMPLE\";\n      const OTHER_TOPIC = \"OTHER\";\n      const CUSTOM_SUBSCRIBE_TOPIC = \"CUSTOM_SUBSCRIBE_TOPIC\";\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        dummyQuery(): boolean {\n          return true;\n        }\n\n        @Mutation(() => Boolean)\n        async pubSubMutation(@Arg(\"value\") value: number): Promise<boolean> {\n          pubSub.publish(SAMPLE_TOPIC, value);\n          return true;\n        }\n\n        @Mutation(() => Boolean)\n        async pubSubMutationCustomSubscription(@Arg(\"value\") value: number): Promise<boolean> {\n          pubSub.publish(CUSTOM_SUBSCRIBE_TOPIC, value);\n          return true;\n        }\n\n        @Mutation(() => Boolean)\n        async pubSubMutationDynamicTopic(\n          @Arg(\"value\") value: number,\n          @Arg(\"topic\") topic: string,\n        ): Promise<boolean> {\n          pubSub.publish(topic, value);\n          return true;\n        }\n\n        @Mutation(() => Boolean)\n        async pubSubOtherMutation(@Arg(\"value\") value: number): Promise<boolean> {\n          pubSub.publish(OTHER_TOPIC, value);\n          return true;\n        }\n\n        @Subscription({\n          topics: SAMPLE_TOPIC,\n        })\n        sampleTopicSubscription(@Root() value: number): SampleObject {\n          return { value };\n        }\n\n        @Subscription({\n          topics: SAMPLE_TOPIC,\n          filter: ({ payload: value }) => value > 0.5,\n        })\n        sampleTopicSubscriptionWithFilter(@Root() value: number): SampleObject {\n          return { value };\n        }\n\n        @Subscription({\n          topics: [SAMPLE_TOPIC, OTHER_TOPIC],\n        })\n        multipleTopicSubscription(@Root() value: number): SampleObject {\n          return { value };\n        }\n\n        @Subscription({\n          topics: ({ args }) => args.topic,\n        })\n        dynamicTopicSubscription(\n          @Root() value: number,\n          @Arg(\"topic\") _topic: string,\n        ): SampleObject {\n          return { value };\n        }\n\n        @Subscription({\n          subscribe: () => pubSub.subscribe(CUSTOM_SUBSCRIBE_TOPIC),\n        })\n        customSubscribeSubscription(@Root() value: number): SampleObject {\n          return { value };\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        pubSub,\n      });\n    });\n\n    it(\"should build schema without errors\", async () => {\n      expect(schema).toBeDefined();\n    });\n\n    async function subscribeOnceAndMutate(options: {\n      mutation: DocumentNode;\n      mutationVariables?: object;\n      subscription: DocumentNode;\n      subscriptionVariables?: object;\n      onSubscribedData: (data: any) => void;\n    }) {\n      const results = (await subscribe({\n        schema,\n        document: options.subscription,\n        variableValues: options.subscriptionVariables as any,\n      })) as AsyncIterableIterator<ExecutionResult>;\n      const onDataPromise = results.next().then(async ({ value }) => {\n        options.onSubscribedData(value.data);\n      });\n      await execute({\n        schema,\n        document: options.mutation,\n        variableValues: options.mutationVariables as any,\n      });\n      await onDataPromise;\n    }\n\n    it(\"should successfully get data from subscription after publishing mutation\", async () => {\n      let subscriptionValue!: number;\n      const testedValue = Math.PI;\n      const subscription = gql`\n        subscription {\n          sampleTopicSubscription {\n            value\n          }\n        }\n      `;\n      const mutation = gql`\n        mutation {\n          pubSubMutation(value: ${testedValue})\n        }\n      `;\n\n      await subscribeOnceAndMutate({\n        subscription,\n        mutation,\n        onSubscribedData: data => {\n          subscriptionValue = data.sampleTopicSubscription.value;\n        },\n      });\n\n      expect(subscriptionValue).toEqual(testedValue);\n    });\n\n    it(\"should successfully get data from subscription using fragments\", async () => {\n      let subscriptionValue!: number;\n      const testedValue = Math.PI;\n      const subscription = gql`\n        fragment TestFragment on SampleObject {\n          value\n        }\n        subscription {\n          sampleTopicSubscription {\n            ...TestFragment\n          }\n        }\n      `;\n      const mutation = gql`\n        mutation {\n          pubSubMutation(value: ${testedValue})\n        }\n      `;\n\n      await subscribeOnceAndMutate({\n        subscription,\n        mutation,\n        onSubscribedData: data => {\n          subscriptionValue = data.sampleTopicSubscription.value;\n        },\n      });\n\n      expect(subscriptionValue).toEqual(testedValue);\n    });\n\n    it(\"should successfully get data from subscription after sequential mutations\", async () => {\n      let subscriptionValue!: number;\n      const subscriptionQuery = gql`\n        subscription {\n          sampleTopicSubscription {\n            value\n          }\n        }\n      `;\n      const mutation = gql`\n        mutation SimpleMutation($value: Float!) {\n          pubSubMutation(value: $value)\n        }\n      `;\n\n      const subscription = (await subscribe({\n        schema,\n        document: subscriptionQuery,\n      })) as AsyncIterableIterator<ExecutionResult>;\n      // run subscription in a separate async \"thread\"\n      (async () => {\n        for await (const result of subscription) {\n          subscriptionValue = (result.data as any).sampleTopicSubscription.value;\n        }\n      })();\n\n      await execute({ schema, document: mutation, variableValues: { value: 1.23 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(1.23);\n\n      await execute({ schema, document: mutation, variableValues: { value: 2.37 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(2.37);\n\n      await execute({ schema, document: mutation, variableValues: { value: 4.53 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(4.53);\n    });\n\n    it(\"should doesn't trigger subscription when published to other topic\", async () => {\n      let subscriptionValue!: number;\n      const subscriptionQuery = gql`\n        subscription {\n          sampleTopicSubscription {\n            value\n          }\n        }\n      `;\n      const sampleTopicMutation = gql`\n        mutation SampleTopicMutation($value: Float!) {\n          pubSubMutation(value: $value)\n        }\n      `;\n      const otherTopicMutation = gql`\n        mutation OtherTopicMutation($value: Float!) {\n          pubSubOtherMutation(value: $value)\n        }\n      `;\n\n      const subscription = (await subscribe({\n        schema,\n        document: subscriptionQuery,\n      })) as AsyncIterableIterator<ExecutionResult>;\n      // run subscription in a separate async \"thread\"\n      (async () => {\n        for await (const result of subscription) {\n          subscriptionValue = (result.data as any).sampleTopicSubscription.value;\n        }\n      })();\n\n      await execute({ schema, document: otherTopicMutation, variableValues: { value: 1.23 } });\n      await sleep(0);\n      expect(subscriptionValue).toBeUndefined();\n\n      await execute({ schema, document: otherTopicMutation, variableValues: { value: 2.37 } });\n      await sleep(0);\n      expect(subscriptionValue).toBeUndefined();\n\n      await execute({ schema, document: sampleTopicMutation, variableValues: { value: 3.47 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(3.47);\n    });\n\n    it(\"should correctly filter triggering subscription\", async () => {\n      let subscriptionValue!: number;\n      const subscriptionQuery = gql`\n        subscription {\n          sampleTopicSubscriptionWithFilter {\n            value\n          }\n        }\n      `;\n      const mutation = gql`\n        mutation SimpleMutation($value: Float!) {\n          pubSubMutation(value: $value)\n        }\n      `;\n\n      const subscription = (await subscribe({\n        schema,\n        document: subscriptionQuery,\n      })) as AsyncIterableIterator<ExecutionResult>;\n      // run subscription in a separate async \"thread\"\n      (async () => {\n        for await (const result of subscription) {\n          subscriptionValue = (result.data as any).sampleTopicSubscriptionWithFilter.value;\n        }\n      })();\n\n      await execute({ schema, document: mutation, variableValues: { value: 0.23 } });\n      await sleep(0);\n      expect(subscriptionValue).toBeUndefined();\n\n      await execute({ schema, document: mutation, variableValues: { value: 0.77 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(0.77);\n\n      await execute({ schema, document: mutation, variableValues: { value: 0.44 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(0.77);\n    });\n\n    it(\"should correctly subscribe to multiple topics\", async () => {\n      let subscriptionValue!: number;\n      const subscriptionQuery = gql`\n        subscription {\n          multipleTopicSubscription {\n            value\n          }\n        }\n      `;\n      const sampleTopicMutation = gql`\n        mutation SampleTopicMutation($value: Float!) {\n          pubSubMutation(value: $value)\n        }\n      `;\n      const otherTopicMutation = gql`\n        mutation OtherTopicMutation($value: Float!) {\n          pubSubOtherMutation(value: $value)\n        }\n      `;\n\n      const subscription = (await subscribe({\n        schema,\n        document: subscriptionQuery,\n      })) as AsyncIterableIterator<ExecutionResult>;\n      // run subscription in a separate async \"thread\"\n      (async () => {\n        for await (const result of subscription) {\n          subscriptionValue = (result.data as any).multipleTopicSubscription.value;\n        }\n      })();\n\n      await execute({ schema, document: sampleTopicMutation, variableValues: { value: 0.23 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(0.23);\n\n      await execute({ schema, document: otherTopicMutation, variableValues: { value: 0.77 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(0.77);\n\n      await execute({ schema, document: sampleTopicMutation, variableValues: { value: 0.44 } });\n      await sleep(0);\n      expect(subscriptionValue).toEqual(0.44);\n    });\n\n    it(\"should correctly subscribe to dynamic topics\", async () => {\n      let subscriptionValue!: number;\n      const SAMPLE_TOPIC = \"MY_DYNAMIC_TOPIC\";\n      const dynamicTopicSubscription = gql`\n        subscription dynamicTopicSubscription($topic: String!) {\n          dynamicTopicSubscription(topic: $topic) {\n            value\n          }\n        }\n      `;\n      const pubSubMutationDynamicTopic = gql`\n        mutation pubSubMutationDynamicTopic($value: Float!, $topic: String!) {\n          pubSubMutationDynamicTopic(value: $value, topic: $topic)\n        }\n      `;\n\n      await subscribeOnceAndMutate({\n        subscription: dynamicTopicSubscription,\n        subscriptionVariables: { topic: SAMPLE_TOPIC },\n        mutation: pubSubMutationDynamicTopic,\n        mutationVariables: { value: 0.23, topic: SAMPLE_TOPIC },\n        onSubscribedData: data => {\n          subscriptionValue = data.dynamicTopicSubscription.value;\n        },\n      });\n\n      expect(subscriptionValue).toEqual(0.23);\n    });\n\n    it(\"should correctly subscribe with custom subscribe function\", async () => {\n      let subscriptionValue!: number;\n      const testedValue = Math.PI;\n      const subscription = gql`\n        subscription {\n          customSubscribeSubscription {\n            value\n          }\n        }\n      `;\n      const mutation = gql`\n        mutation {\n          pubSubMutationCustomSubscription(value: ${testedValue})\n        }\n      `;\n\n      await subscribeOnceAndMutate({\n        subscription,\n        mutation,\n        onSubscribedData: data => {\n          subscriptionValue = data.customSubscribeSubscription.value;\n        },\n      });\n\n      expect(subscriptionValue).toEqual(testedValue);\n    });\n  });\n\n  describe(\"errors\", () => {\n    it(\"should throw error when using subscriptions but not providing pub sub implementation\", async () => {\n      getMetadataStorage().clear();\n      const error = await expectToThrow(async () => {\n        class SampleResolver {\n          @Query()\n          dumbQuery(): boolean {\n            return true;\n          }\n\n          @Subscription({ topics: \"TEST\" })\n          sampleSubscription(): boolean {\n            return true;\n          }\n        }\n\n        await buildSchema({\n          resolvers: [SampleResolver],\n          pubSub: undefined,\n        });\n      });\n\n      expect(error).toBeDefined();\n      expect(error).toBeInstanceOf(MissingPubSubError);\n    });\n\n    it(\"should throw error while passing empty topics array to Subscription\", async () => {\n      getMetadataStorage().clear();\n      const error = await expectToThrow(async () => {\n        class SampleResolver {\n          @Query()\n          dumbQuery(): boolean {\n            return true;\n          }\n\n          @Mutation(() => Boolean)\n          async pubSubMutation(@Arg(\"value\") value: number): Promise<boolean> {\n            pubSub.publish(\"TEST\", value);\n            return true;\n          }\n\n          @Subscription({ topics: [] })\n          sampleSubscription(): boolean {\n            return true;\n          }\n        }\n\n        await buildSchema({\n          resolvers: [SampleResolver],\n          pubSub,\n        });\n      });\n\n      expect(error).toBeDefined();\n      expect(error).toBeInstanceOf(MissingSubscriptionTopicsError);\n      expect(error.message).toContain(\"SampleResolver\");\n      expect(error.message).toContain(\"sampleSubscription\");\n      expect(error.message).not.toContain(\"class SampleResolver\");\n    });\n\n    it(\"should throw authorization error just on subscribe\", async () => {\n      getMetadataStorage().clear();\n      // expect.assertions(3);\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleQuery(): number {\n          return 2137;\n        }\n\n        @Authorized(\"prevent\")\n        @Subscription(_returns => Int, { topics: \"SAMPLE_TOPIC\" })\n        authedSubscription(): number {\n          return 0;\n        }\n      }\n      const schema = await buildSchema({\n        resolvers: [SampleResolver],\n        pubSub,\n        authChecker: () => false,\n      });\n      const document = gql`\n        subscription {\n          authedSubscription\n        }\n      `;\n\n      const subscribeResult = await subscribe({ schema, document });\n\n      expect(subscribeResult).toHaveProperty(\"errors\");\n      const { errors } = subscribeResult as ExecutionResult;\n      expect(errors).toHaveLength(1);\n      expect(errors![0].message).toContain(\"Access denied!\");\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/typedefs-resolvers.ts",
    "content": "/* eslint \"no-underscore-dangle\": [\"error\", { \"allow\": [\"__schema\"] }] */\nimport \"reflect-metadata\";\nimport { makeExecutableSchema } from \"@graphql-tools/schema\";\nimport { createPubSub } from \"@graphql-yoga/subscription\";\nimport { MinLength } from \"class-validator\";\nimport {\n  type ExecutionResult,\n  type GraphQLSchema,\n  type IntrospectionEnumType,\n  type IntrospectionInputObjectType,\n  type IntrospectionInterfaceType,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionQuery,\n  type IntrospectionScalarType,\n  type IntrospectionSchema,\n  type IntrospectionUnionType,\n  TypeKind,\n  execute,\n  getIntrospectionQuery,\n  graphql,\n  subscribe,\n} from \"graphql\";\nimport gql from \"graphql-tag\";\nimport {\n  Arg,\n  Authorized,\n  Field,\n  FieldResolver,\n  InputType,\n  InterfaceType,\n  Mutation,\n  ObjectType,\n  type PubSub,\n  Query,\n  Resolver,\n  type ResolverObject,\n  type ResolverOptions,\n  type ResolversMap,\n  Root,\n  Subscription,\n  UseMiddleware,\n  buildTypeDefsAndResolvers,\n  buildTypeDefsAndResolversSync,\n  createUnionType,\n  registerEnumType,\n} from \"type-graphql\";\nimport Container, { Service } from \"typedi\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\n\ndescribe(\"typeDefs and resolvers\", () => {\n  describe(\"buildTypeDefsAndResolvers\", () => {\n    const timestamp = 1547398942902;\n    let typeDefs: string;\n    let resolvers: ResolversMap;\n    let schemaIntrospection: IntrospectionSchema;\n    let schema: GraphQLSchema;\n    let pubSub: PubSub;\n    let inputValue: any;\n    let enumValue: any;\n    let middlewareLogs: string[];\n\n    beforeEach(async () => {\n      middlewareLogs = [];\n      enumValue = undefined;\n    });\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @Service()\n      class SampleService {\n        getSampleString() {\n          return \"SampleString\";\n        }\n      }\n\n      @InterfaceType()\n      abstract class SampleInterface {\n        @Field()\n        sampleInterfaceStringField!: string;\n      }\n\n      @ObjectType({ implements: SampleInterface })\n      class SampleType1 implements SampleInterface {\n        @Field()\n        sampleInterfaceStringField!: string;\n\n        @Field({ description: \"sampleType1StringFieldDescription\" })\n        sampleType1StringField!: string;\n      }\n\n      @ObjectType({ implements: SampleInterface })\n      class SampleType2 implements SampleInterface {\n        @Field()\n        sampleInterfaceStringField!: string;\n\n        @Field({ deprecationReason: \"sampleType2StringFieldDeprecation\" })\n        sampleType2StringField!: string;\n      }\n\n      @ObjectType()\n      class SampleType3 {\n        @Field()\n        sampleInterfaceStringField!: string;\n\n        @Field()\n        sampleType3StringField!: string;\n      }\n\n      @ObjectType(\"SampleType__4\")\n      class SampleType4 {\n        @Field()\n        sampleInterfaceStringField!: string;\n\n        @Field()\n        sampleType4StringField!: string;\n      }\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        @MinLength(10)\n        sampleInputStringField!: string;\n\n        @Field()\n        sampleInputDefaultStringField: string = \"sampleInputDefaultStringField\";\n      }\n\n      enum SampleNumberEnum {\n        OptionOne,\n        OptionTwo,\n      }\n      registerEnumType(SampleNumberEnum, { name: \"SampleNumberEnum\" });\n\n      enum SampleStringEnum {\n        OptionOne = \"OptionOneString\",\n        OptionTwo = \"OptionTwoString\",\n      }\n      registerEnumType(SampleStringEnum, { name: \"SampleStringEnum\" });\n\n      const SampleUnion = createUnionType({\n        types: () => [SampleType2, SampleType3],\n        name: \"SampleUnion\",\n        description: \"SampleUnion description\",\n      });\n\n      const SampleResolveUnion = createUnionType({\n        types: () => [SampleType2, SampleType3],\n        name: \"SampleResolveUnion\",\n        resolveType: value => {\n          if (\"sampleType2StringField\" in value) {\n            return \"SampleType2\";\n          }\n          if (\"sampleType3StringField\" in value) {\n            return \"SampleType3\";\n          }\n          return undefined;\n        },\n      });\n\n      @Service()\n      @Resolver()\n      class SampleResolver {\n        constructor(private readonly sampleService: SampleService) {}\n\n        @Query({ description: \"sampleDateQueryDescription\" })\n        sampleDateQuery(): Date {\n          return new Date(timestamp);\n        }\n\n        @Query()\n        sampleServiceQuery(): string {\n          return this.sampleService.getSampleString();\n        }\n\n        @Query()\n        @UseMiddleware(async (_, next) => {\n          middlewareLogs.push(\"sampleMiddlewareBooleanQuery\");\n          return next();\n        })\n        sampleMiddlewareBooleanQuery(): boolean {\n          return true;\n        }\n\n        @Mutation()\n        sampleBooleanMutation(): boolean {\n          return true;\n        }\n\n        @Mutation()\n        sampleMutationWithInput(@Arg(\"input\") input: SampleInput): boolean {\n          inputValue = input;\n          return true;\n        }\n\n        @Mutation()\n        @Authorized()\n        sampleAuthorizedMutation(): boolean {\n          return true;\n        }\n\n        @Query()\n        sampleInterfaceQuery(): SampleInterface {\n          const type1 = new SampleType1();\n          type1.sampleInterfaceStringField = \"sampleInterfaceStringField\";\n          type1.sampleType1StringField = \"sampleType1StringField\";\n\n          return type1;\n        }\n\n        @Query(() => SampleUnion)\n        sampleUnionQuery(): typeof SampleUnion {\n          const type3 = new SampleType3();\n          type3.sampleInterfaceStringField = \"sampleInterfaceStringField\";\n          type3.sampleType3StringField = \"sampleType3StringField\";\n\n          return type3;\n        }\n\n        @Query(() => SampleResolveUnion)\n        sampleResolveUnionQuery(): typeof SampleResolveUnion {\n          return {\n            sampleInterfaceStringField: \"sampleInterfaceStringField\",\n            sampleType3StringField: \"sampleType3StringField\",\n          };\n        }\n\n        @Query(() => SampleNumberEnum)\n        sampleNumberEnumQuery(\n          @Arg(\"numberEnum\", () => SampleNumberEnum) numberEnum: SampleNumberEnum,\n        ): SampleNumberEnum {\n          enumValue = numberEnum;\n          return numberEnum;\n        }\n\n        @Query(() => SampleStringEnum)\n        sampleStringEnumQuery(\n          @Arg(\"stringEnum\", () => SampleStringEnum) stringEnum: SampleStringEnum,\n        ): SampleStringEnum {\n          enumValue = stringEnum;\n          return stringEnum;\n        }\n\n        @Subscription({\n          topics: \"SAMPLE\",\n        })\n        sampleSubscription(@Root() payload: number): number {\n          return payload;\n        }\n      }\n\n      pubSub = createPubSub();\n\n      @Service()\n      @Resolver(() => SampleType4)\n      class SampleObjectTypeWithDoubleUnderscoreInNameResolver {\n        @FieldResolver(() => String)\n        sampleResolvedField(): string {\n          return \"sampleResolvedField\";\n        }\n\n        @Query(() => SampleType4)\n        async sampleQueryOnObjectTypeWithDoubleUnderScore(): Promise<SampleType4> {\n          const type4 = new SampleType4();\n          type4.sampleInterfaceStringField = \"sampleInterfaceStringField\";\n          type4.sampleType4StringField = \"sampleType4StringField\";\n          return type4;\n        }\n      }\n\n      ({ typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n        resolvers: [SampleResolver, SampleObjectTypeWithDoubleUnderscoreInNameResolver],\n        authChecker: () => false,\n        pubSub,\n        container: Container,\n        orphanedTypes: [SampleType1],\n        validate: true,\n      }));\n      schema = makeExecutableSchema({\n        typeDefs,\n        resolvers,\n      });\n      const introspectionResult = await graphql({ schema, source: getIntrospectionQuery() });\n      schemaIntrospection = (introspectionResult.data as unknown as IntrospectionQuery).__schema;\n    });\n\n    it(\"should generate schema without errors\", () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    describe(\"typeDefs\", () => {\n      it(\"should generate typeDefs correctly\", async () => {\n        expect(typeDefs).toBeDefined();\n      });\n\n      it(\"should generate interface type\", async () => {\n        const sampleInterface = schemaIntrospection.types.find(\n          it => it.name === \"SampleInterface\",\n        ) as IntrospectionInterfaceType;\n\n        expect(sampleInterface.kind).toBe(TypeKind.INTERFACE);\n        expect(sampleInterface.fields).toHaveLength(1);\n        expect(sampleInterface.fields[0].name).toBe(\"sampleInterfaceStringField\");\n        expect(sampleInterface.possibleTypes).toHaveLength(2);\n        expect(sampleInterface.possibleTypes.map(it => it.name)).toContain(\"SampleType1\");\n        expect(sampleInterface.possibleTypes.map(it => it.name)).toContain(\"SampleType2\");\n      });\n\n      it(\"should generate object types\", async () => {\n        const sampleType1 = schemaIntrospection.types.find(\n          it => it.name === \"SampleType1\",\n        ) as IntrospectionObjectType;\n        const sampleType2 = schemaIntrospection.types.find(\n          it => it.name === \"SampleType2\",\n        ) as IntrospectionObjectType;\n        const sampleType4 = schemaIntrospection.types.find(\n          it => it.name === \"SampleType__4\",\n        ) as IntrospectionObjectType;\n\n        const sampleType1StringField = sampleType1.fields.find(\n          it => it.name === \"sampleType1StringField\",\n        )!;\n        const sampleType2StringField = sampleType2.fields.find(\n          it => it.name === \"sampleType2StringField\",\n        )!;\n\n        expect(sampleType1.kind).toBe(TypeKind.OBJECT);\n        expect(sampleType1.fields).toHaveLength(2);\n        expect(sampleType1StringField.description).toEqual(\"sampleType1StringFieldDescription\");\n        expect(sampleType1.interfaces).toHaveLength(1);\n        expect(sampleType1.interfaces[0].name).toBe(\"SampleInterface\");\n        expect(sampleType2StringField.deprecationReason).toBe(\"sampleType2StringFieldDeprecation\");\n        expect(sampleType4.fields).toHaveLength(3);\n      });\n\n      it(\"should generate input type\", async () => {\n        const sampleInput = schemaIntrospection.types.find(\n          it => it.name === \"SampleInput\",\n        ) as IntrospectionInputObjectType;\n        const sampleInputDefaultStringField = sampleInput.inputFields.find(\n          it => it.name === \"sampleInputDefaultStringField\",\n        )!;\n        const sampleInputDefaultStringFieldType =\n          sampleInputDefaultStringField.type as IntrospectionNamedTypeRef;\n\n        expect(sampleInput.kind).toBe(TypeKind.INPUT_OBJECT);\n        expect(sampleInput.inputFields).toHaveLength(2);\n        expect(sampleInputDefaultStringFieldType).toEqual({\n          kind: \"NON_NULL\",\n          name: null,\n          ofType: {\n            kind: \"SCALAR\",\n            name: \"String\",\n            ofType: null,\n          },\n        });\n        expect(sampleInputDefaultStringField.defaultValue).toBe('\"sampleInputDefaultStringField\"');\n      });\n\n      it(\"should generate enum types\", async () => {\n        const sampleNumberEnum = schemaIntrospection.types.find(\n          it => it.name === \"SampleNumberEnum\",\n        ) as IntrospectionEnumType;\n        const sampleStringEnum = schemaIntrospection.types.find(\n          it => it.name === \"SampleStringEnum\",\n        ) as IntrospectionEnumType;\n\n        expect(sampleNumberEnum.kind).toBe(TypeKind.ENUM);\n        expect(sampleNumberEnum).toBeDefined();\n        expect(sampleNumberEnum.enumValues).toHaveLength(2);\n        expect(sampleStringEnum.enumValues).toHaveLength(2);\n      });\n\n      it(\"should generate union type\", async () => {\n        const sampleUnion = schemaIntrospection.types.find(\n          it => it.name === \"SampleUnion\",\n        ) as IntrospectionUnionType;\n\n        expect(sampleUnion.kind).toBe(TypeKind.UNION);\n        expect(sampleUnion.description).toBe(\"SampleUnion description\");\n        expect(sampleUnion.possibleTypes).toHaveLength(2);\n        expect(sampleUnion.possibleTypes.map(it => it.name)).toContain(\"SampleType2\");\n        expect(sampleUnion.possibleTypes.map(it => it.name)).toContain(\"SampleType3\");\n      });\n\n      it(\"should generate queries\", async () => {\n        const queryType = schemaIntrospection.types.find(\n          it => it.name === schemaIntrospection.queryType.name,\n        ) as IntrospectionObjectType;\n\n        expect(queryType.fields).toHaveLength(9);\n      });\n\n      it(\"should generate mutations\", async () => {\n        const mutationType = schemaIntrospection.types.find(\n          it => it.name === schemaIntrospection.mutationType!.name,\n        ) as IntrospectionObjectType;\n\n        expect(mutationType.fields).toHaveLength(3);\n      });\n\n      it(\"should generate subscription\", async () => {\n        const subscriptionType = schemaIntrospection.types.find(\n          it => it.name === schemaIntrospection.subscriptionType!.name,\n        ) as IntrospectionObjectType;\n\n        expect(subscriptionType.fields).toHaveLength(1);\n      });\n\n      it(\"should emit Date scalar\", async () => {\n        const dateScalar = schemaIntrospection.types.find(\n          it => it.name === \"DateTimeISO\",\n        ) as IntrospectionScalarType;\n\n        expect(dateScalar.kind).toBe(TypeKind.SCALAR);\n      });\n    });\n\n    describe(\"resolvers\", () => {\n      it(\"should generate resolversMap without errors\", async () => {\n        expect(resolvers).toBeDefined();\n      });\n\n      it(\"should not emit `__isTypeOf` for root objects\", async () => {\n        expect(resolvers.Query).not.toHaveProperty(\"__isTypeOf\");\n        expect(resolvers.Mutation).not.toHaveProperty(\"__isTypeOf\");\n        expect(resolvers.Subscription).not.toHaveProperty(\"__isTypeOf\");\n      });\n\n      it(\"should properly serialize Date scalar\", async () => {\n        const document = gql`\n          query {\n            sampleDateQuery\n          }\n        `;\n\n        const result: any = await execute({ schema, document });\n        const parsedDate = new Date(result.data.sampleDateQuery);\n\n        expect(typeof result.data.sampleDateQuery).toBe(\"string\");\n        expect(parsedDate.getTime()).toEqual(timestamp);\n      });\n\n      it(\"should use container to resolve dependency\", async () => {\n        const document = gql`\n          query {\n            sampleServiceQuery\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleServiceQuery).toEqual(\"SampleString\");\n      });\n\n      it(\"should run resolver method middleware\", async () => {\n        const document = gql`\n          query {\n            sampleMiddlewareBooleanQuery\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleMiddlewareBooleanQuery).toEqual(true);\n        expect(middlewareLogs).toHaveLength(1);\n        expect(middlewareLogs[0]).toEqual(\"sampleMiddlewareBooleanQuery\");\n      });\n\n      it(\"should allow for simple boolean mutation\", async () => {\n        const document = gql`\n          mutation {\n            sampleBooleanMutation\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleBooleanMutation).toBe(true);\n      });\n\n      it(\"should properly transform input argument\", async () => {\n        const document = gql`\n          mutation {\n            sampleMutationWithInput(input: { sampleInputStringField: \"sampleInputStringField\" })\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleMutationWithInput).toBe(true);\n        expect(inputValue.constructor.name).toBe(\"SampleInput\");\n        expect(inputValue.sampleInputStringField).toBe(\"sampleInputStringField\");\n        expect(inputValue.sampleInputDefaultStringField).toBe(\"sampleInputDefaultStringField\");\n      });\n\n      it(\"should validate the input\", async () => {\n        const document = gql`\n          mutation {\n            sampleMutationWithInput(input: { sampleInputStringField: \"short\" })\n          }\n        `;\n\n        const { errors } = await execute({ schema, document });\n\n        expect(errors).toHaveLength(1);\n        expect(errors![0].message).toContain(\"Argument Validation Error\");\n      });\n\n      it(\"should properly guard authorized resolver method\", async () => {\n        const document = gql`\n          mutation {\n            sampleAuthorizedMutation\n          }\n        `;\n\n        const { errors } = await execute({ schema, document });\n\n        expect(errors).toHaveLength(1);\n        expect(errors![0].message).toContain(\"Access denied\");\n      });\n\n      it(\"should detect returned object type from interface\", async () => {\n        const document = gql`\n          query {\n            sampleInterfaceQuery {\n              sampleInterfaceStringField\n              ... on SampleType1 {\n                sampleType1StringField\n              }\n            }\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleInterfaceQuery).toEqual({\n          sampleInterfaceStringField: \"sampleInterfaceStringField\",\n          sampleType1StringField: \"sampleType1StringField\",\n        });\n      });\n\n      it(\"should detect returned object type from union\", async () => {\n        const document = gql`\n          query {\n            sampleUnionQuery {\n              ... on SampleType3 {\n                sampleInterfaceStringField\n                sampleType3StringField\n              }\n            }\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleUnionQuery).toEqual({\n          sampleInterfaceStringField: \"sampleInterfaceStringField\",\n          sampleType3StringField: \"sampleType3StringField\",\n        });\n      });\n\n      it(\"should detect returned object type using resolveType from union\", async () => {\n        const document = gql`\n          query {\n            sampleResolveUnionQuery {\n              ... on SampleType3 {\n                sampleInterfaceStringField\n                sampleType3StringField\n              }\n            }\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleResolveUnionQuery).toEqual({\n          sampleInterfaceStringField: \"sampleInterfaceStringField\",\n          sampleType3StringField: \"sampleType3StringField\",\n        });\n      });\n\n      it(\"should properly transform number enum argument\", async () => {\n        const document = gql`\n          query {\n            sampleNumberEnumQuery(numberEnum: OptionOne)\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleNumberEnumQuery).toBe(\"OptionOne\");\n        expect(enumValue).toBe(0);\n      });\n\n      it(\"should properly transform string enum argument\", async () => {\n        const document = gql`\n          query {\n            sampleStringEnumQuery(stringEnum: OptionTwo)\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleStringEnumQuery).toBe(\"OptionTwo\");\n        expect(enumValue).toBe(\"OptionTwoString\");\n      });\n\n      it(\"should properly execute field resolver for object type with two underscores NOT in the beginning\", async () => {\n        const document = gql`\n          query {\n            sampleQueryOnObjectTypeWithDoubleUnderScore {\n              sampleResolvedField\n              sampleInterfaceStringField\n              sampleType4StringField\n            }\n          }\n        `;\n\n        const { data } = await execute({ schema, document });\n\n        expect(data!.sampleQueryOnObjectTypeWithDoubleUnderScore).toEqual({\n          sampleResolvedField: \"sampleResolvedField\",\n          sampleInterfaceStringField: \"sampleInterfaceStringField\",\n          sampleType4StringField: \"sampleType4StringField\",\n        });\n      });\n\n      it(\"should properly run subscriptions\", async () => {\n        const document = gql`\n          subscription {\n            sampleSubscription\n          }\n        `;\n        const payload = 5.4321;\n\n        const iterator = (await subscribe({ schema, document })) as AsyncIterator<ExecutionResult>;\n        const firstValuePromise = iterator.next();\n        pubSub.publish(\"SAMPLE\", payload);\n        const data = await firstValuePromise;\n\n        expect(data.value.data!.sampleSubscription).toBe(payload);\n      });\n\n      it(\"should generate simple resolvers function for queries and mutations\", async () => {\n        expect((resolvers.Query as ResolverObject<any, any>).sampleDateQuery).toBeInstanceOf(\n          Function,\n        );\n        expect(\n          (resolvers.Mutation as ResolverObject<any, any>).sampleBooleanMutation,\n        ).toBeInstanceOf(Function);\n      });\n\n      it(\"should generate resolvers object for subscriptions\", async () => {\n        const sampleSubscription = (resolvers.Subscription as ResolverObject<any, any>)\n          .sampleSubscription as ResolverOptions<any, any>;\n\n        expect(sampleSubscription.resolve).toBeInstanceOf(Function);\n        expect(sampleSubscription.subscribe).toBeInstanceOf(Function);\n      });\n    });\n  });\n\n  describe(\"buildTypeDefsAndResolversSync\", () => {\n    let typeDefs: string;\n    let resolvers: ResolversMap;\n    let schemaIntrospection: IntrospectionSchema;\n    let schema: GraphQLSchema;\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleType {\n        @Field()\n        sampleInterfaceStringField!: string;\n\n        @Field({ description: \"sampleTypeStringFieldDescription\" })\n        sampleTypeStringField!: string;\n      }\n\n      @Resolver()\n      class SampleResolver {\n        @Query()\n        sampleBooleanQuery(): boolean {\n          return true;\n        }\n      }\n\n      ({ typeDefs, resolvers } = buildTypeDefsAndResolversSync({\n        resolvers: [SampleResolver],\n        authChecker: () => false,\n        orphanedTypes: [SampleType],\n      }));\n      schema = makeExecutableSchema({\n        typeDefs,\n        resolvers,\n      });\n      const introspectionResult = await graphql({ schema, source: getIntrospectionQuery() });\n      schemaIntrospection = (introspectionResult.data as unknown as IntrospectionQuery).__schema;\n    });\n\n    it(\"should generate schema without errors\", () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    describe(\"typeDefs\", () => {\n      it(\"should generate typeDefs correctly\", async () => {\n        expect(typeDefs).toBeDefined();\n      });\n\n      it(\"should generate object types\", async () => {\n        const sampleType = schemaIntrospection.types.find(\n          it => it.name === \"SampleType\",\n        ) as IntrospectionObjectType;\n        const sampleTypeStringField = sampleType.fields.find(\n          it => it.name === \"sampleTypeStringField\",\n        )!;\n\n        expect(sampleType.kind).toBe(TypeKind.OBJECT);\n        expect(sampleType.fields).toHaveLength(2);\n        expect(sampleTypeStringField.description).toEqual(\"sampleTypeStringFieldDescription\");\n        expect(sampleType.interfaces).toHaveLength(0);\n      });\n    });\n\n    describe(\"resolvers\", () => {\n      it(\"should generate resolversMap without errors\", async () => {\n        expect(resolvers).toBeDefined();\n      });\n\n      it(\"should allow for simple boolean query\", async () => {\n        const document = gql`\n          query {\n            sampleBooleanQuery\n          }\n        `;\n\n        const { data, errors } = await execute({ schema, document });\n\n        expect(errors).toBeUndefined();\n        expect(data!.sampleBooleanQuery).toBe(true);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/unions.ts",
    "content": "/* eslint \"no-underscore-dangle\": [\"error\", { \"allow\": [\"__typename\"] }] */\nimport \"reflect-metadata\";\nimport {\n  type GraphQLSchema,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  type IntrospectionUnionType,\n  TypeKind,\n  graphql,\n} from \"graphql\";\nimport { Field, ObjectType, Query, Resolver, buildSchema, createUnionType } from \"type-graphql\";\nimport { getMetadataStorage } from \"@/metadata/getMetadataStorage\";\nimport { getInnerFieldType, getInnerTypeOfNonNullableType } from \"../helpers/getInnerFieldType\";\nimport { getSchemaInfo } from \"../helpers/getSchemaInfo\";\n\ndescribe(\"Unions\", () => {\n  let schemaIntrospection: IntrospectionSchema;\n  let queryType: IntrospectionObjectType;\n  let schema: GraphQLSchema;\n\n  beforeAll(async () => {\n    getMetadataStorage().clear();\n\n    @ObjectType()\n    class ObjectOne {\n      @Field()\n      fieldOne!: string;\n    }\n    @ObjectType()\n    class ObjectTwo {\n      @Field()\n      fieldTwo!: string;\n    }\n    @ObjectType()\n    class ObjectThree {\n      @Field()\n      fieldThree!: string;\n    }\n\n    const OneTwoThreeUnion = createUnionType({\n      name: \"OneTwoThreeUnion\",\n      description: \"OneTwoThreeUnion description\",\n      types: () => [ObjectOne, ObjectTwo, ObjectThree],\n    });\n    const OneTwoThreeUnionFn = createUnionType({\n      name: \"OneTwoThreeUnionFn\",\n      description: \"OneTwoThreeUnionFn description\",\n      types: () => [ObjectOne, ObjectTwo, ObjectThree],\n    });\n\n    const UnionWithStringResolveType = createUnionType({\n      name: \"UnionWithStringResolveType\",\n      types: () => [ObjectOne, ObjectTwo],\n      resolveType: value => {\n        if (\"fieldOne\" in value) {\n          return \"ObjectOne\";\n        }\n        if (\"fieldTwo\" in value) {\n          return \"ObjectTwo\";\n        }\n        return undefined;\n      },\n    });\n\n    const UnionWithClassResolveType = createUnionType({\n      name: \"UnionWithClassResolveType\",\n      types: () => [ObjectOne, ObjectTwo],\n      resolveType: value => {\n        if (\"fieldOne\" in value) {\n          return ObjectOne;\n        }\n        if (\"fieldTwo\" in value) {\n          return ObjectTwo;\n        }\n        return undefined;\n      },\n    });\n\n    @ObjectType()\n    class ObjectUnion {\n      @Field(() => OneTwoThreeUnion)\n      unionField!: typeof OneTwoThreeUnion;\n    }\n\n    class SampleResolver {\n      @Query(() => OneTwoThreeUnion)\n      getObjectOneFromUnion(): typeof OneTwoThreeUnion {\n        const oneInstance = new ObjectTwo();\n        oneInstance.fieldTwo = \"fieldTwo\";\n        return oneInstance;\n      }\n\n      @Query(() => OneTwoThreeUnionFn)\n      getObjectOneFromUnionFn(): typeof OneTwoThreeUnionFn {\n        const oneInstance = new ObjectTwo();\n        oneInstance.fieldTwo = \"fieldTwo\";\n        return oneInstance;\n      }\n\n      @Query()\n      getObjectWithUnion(): ObjectUnion {\n        const oneInstance = new ObjectTwo();\n        oneInstance.fieldTwo = \"fieldTwo\";\n        return {\n          unionField: oneInstance,\n        };\n      }\n\n      @Query(() => OneTwoThreeUnion)\n      getPlainObjectFromUnion(): typeof OneTwoThreeUnion {\n        return {\n          fieldTwo: \"fieldTwo\",\n        };\n      }\n\n      @Query(() => UnionWithStringResolveType)\n      getObjectOneFromStringResolveTypeUnion(): typeof UnionWithStringResolveType {\n        return {\n          fieldTwo: \"fieldTwo\",\n        };\n      }\n\n      @Query(() => UnionWithClassResolveType)\n      getObjectOneFromClassResolveTypeUnion(): typeof UnionWithClassResolveType {\n        return {\n          fieldTwo: \"fieldTwo\",\n        };\n      }\n    }\n\n    const schemaInfo = await getSchemaInfo({\n      resolvers: [SampleResolver],\n    });\n    schema = schemaInfo.schema;\n    schemaIntrospection = schemaInfo.schemaIntrospection;\n    queryType = schemaInfo.queryType;\n  });\n\n  describe(\"Schema\", () => {\n    it(\"should generate schema without errors\", async () => {\n      expect(schemaIntrospection).toBeDefined();\n    });\n\n    it(\"should correctly generate union type\", async () => {\n      const oneTwoThreeUnionType = schemaIntrospection.types.find(\n        type => type.name === \"OneTwoThreeUnion\",\n      ) as IntrospectionUnionType;\n      const objectOne = oneTwoThreeUnionType.possibleTypes.find(type => type.name === \"ObjectOne\")!;\n      const objectTwo = oneTwoThreeUnionType.possibleTypes.find(type => type.name === \"ObjectTwo\")!;\n      const objectThree = oneTwoThreeUnionType.possibleTypes.find(\n        type => type.name === \"ObjectThree\",\n      )!;\n\n      expect(oneTwoThreeUnionType.kind).toEqual(TypeKind.UNION);\n      expect(oneTwoThreeUnionType.name).toEqual(\"OneTwoThreeUnion\");\n      expect(oneTwoThreeUnionType.description).toEqual(\"OneTwoThreeUnion description\");\n      expect(objectOne.kind).toEqual(TypeKind.OBJECT);\n      expect(objectTwo.kind).toEqual(TypeKind.OBJECT);\n      expect(objectThree.kind).toEqual(TypeKind.OBJECT);\n    });\n\n    it(\"should correctly generate union type from function syntax\", async () => {\n      const oneTwoThreeUnionFnType = schemaIntrospection.types.find(\n        type => type.name === \"OneTwoThreeUnionFn\",\n      ) as IntrospectionUnionType;\n      const objectOne = oneTwoThreeUnionFnType.possibleTypes.find(\n        type => type.name === \"ObjectOne\",\n      )!;\n      const objectTwo = oneTwoThreeUnionFnType.possibleTypes.find(\n        type => type.name === \"ObjectTwo\",\n      )!;\n      const objectThree = oneTwoThreeUnionFnType.possibleTypes.find(\n        type => type.name === \"ObjectThree\",\n      )!;\n\n      expect(oneTwoThreeUnionFnType.kind).toEqual(TypeKind.UNION);\n      expect(oneTwoThreeUnionFnType.name).toEqual(\"OneTwoThreeUnionFn\");\n      expect(oneTwoThreeUnionFnType.description).toEqual(\"OneTwoThreeUnionFn description\");\n      expect(objectOne.kind).toEqual(TypeKind.OBJECT);\n      expect(objectTwo.kind).toEqual(TypeKind.OBJECT);\n      expect(objectThree.kind).toEqual(TypeKind.OBJECT);\n    });\n\n    it(\"should correctly generate query's union output type\", async () => {\n      const getObjectOneFromUnion = queryType.fields.find(\n        field => field.name === \"getObjectOneFromUnion\",\n      )!;\n\n      const getObjectOneFromUnionType = getInnerTypeOfNonNullableType(getObjectOneFromUnion);\n      expect(getObjectOneFromUnionType.kind).toEqual(TypeKind.UNION);\n      expect(getObjectOneFromUnionType.name).toEqual(\"OneTwoThreeUnion\");\n    });\n\n    it(\"should correctly generate object type's union output type\", async () => {\n      const objectUnion = schemaIntrospection.types.find(\n        type => type.name === \"ObjectUnion\",\n      ) as IntrospectionObjectType;\n      const objectUnionFieldType = getInnerFieldType(objectUnion, \"unionField\");\n\n      expect(objectUnionFieldType.kind).toEqual(TypeKind.UNION);\n      expect(objectUnionFieldType.name).toEqual(\"OneTwoThreeUnion\");\n    });\n  });\n\n  describe(\"Functional\", () => {\n    it(\"should correctly recognize returned object type using default `instance of` check\", async () => {\n      const query = `query {\n        getObjectOneFromUnion {\n          __typename\n          ... on ObjectOne {\n            fieldOne\n          }\n          ... on ObjectTwo {\n            fieldTwo\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data!.getObjectOneFromUnion;\n      expect(data.__typename).toEqual(\"ObjectTwo\");\n      expect(data.fieldTwo).toEqual(\"fieldTwo\");\n      expect(data.fieldOne).toBeUndefined();\n    });\n\n    it(\"should correctly recognize returned object type using string provided by `resolveType` function\", async () => {\n      const query = `query {\n        getObjectOneFromStringResolveTypeUnion {\n          __typename\n          ... on ObjectOne {\n            fieldOne\n          }\n          ... on ObjectTwo {\n            fieldTwo\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data!.getObjectOneFromStringResolveTypeUnion;\n      expect(data.__typename).toEqual(\"ObjectTwo\");\n      expect(data.fieldTwo).toEqual(\"fieldTwo\");\n      expect(data.fieldOne).toBeUndefined();\n    });\n\n    it(\"should correctly recognize returned object type using class provided by `resolveType` function\", async () => {\n      const query = `query {\n        getObjectOneFromClassResolveTypeUnion {\n          __typename\n          ... on ObjectOne {\n            fieldOne\n          }\n          ... on ObjectTwo {\n            fieldTwo\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const data = result.data!.getObjectOneFromClassResolveTypeUnion;\n      expect(data.__typename).toEqual(\"ObjectTwo\");\n      expect(data.fieldTwo).toEqual(\"fieldTwo\");\n      expect(data.fieldOne).toBeUndefined();\n    });\n\n    it(\"should correctly recognize returned object type from union on object field\", async () => {\n      const query = `query {\n        getObjectWithUnion {\n          unionField {\n            __typename\n            ... on ObjectOne {\n              fieldOne\n            }\n            ... on ObjectTwo {\n              fieldTwo\n            }\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      const unionFieldData = result.data!.getObjectWithUnion.unionField;\n\n      expect(unionFieldData.__typename).toEqual(\"ObjectTwo\");\n      expect(unionFieldData.fieldTwo).toEqual(\"fieldTwo\");\n      expect(unionFieldData.fieldOne).toBeUndefined();\n    });\n\n    it(\"should throw error when not returning instance of object class\", async () => {\n      const query = `query {\n        getPlainObjectFromUnion {\n          __typename\n          ... on ObjectOne {\n            fieldOne\n          }\n          ... on ObjectTwo {\n            fieldTwo\n          }\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n      const errorMessage = result.errors![0].message;\n      expect(errorMessage).toContain(\"resolve\");\n      expect(errorMessage).toContain(\"OneTwoThreeUnion\");\n      expect(errorMessage).toContain(\"instance\");\n      expect(errorMessage).toContain(\"plain\");\n    });\n  });\n\n  describe(\"typings\", () => {\n    it(\"should correctly transform to TS union type when using extending classes\", async () => {\n      getMetadataStorage().clear();\n      @ObjectType()\n      class Base {\n        @Field()\n        base!: string;\n      }\n      @ObjectType()\n      class Extended extends Base {\n        @Field()\n        extended!: string;\n      }\n\n      expect(() => {\n        createUnionType({\n          name: \"ExtendedBase\",\n          types: () => [Base, Extended] as const,\n        });\n      }).not.toThrow();\n    });\n  });\n\n  describe(\"Multiple schemas\", () => {\n    it(\"should correctly return data from union query for all schemas that uses the same union\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class One {\n        @Field()\n        one!: string;\n      }\n      @ObjectType()\n      class Two {\n        @Field()\n        two!: string;\n      }\n      const OneTwo = createUnionType({\n        name: \"OneTwo\",\n        types: () => [One, Two],\n      });\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => OneTwo)\n        oneTwo(): typeof OneTwo {\n          const one = new One();\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          oneTwo {\n            __typename\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should correctly return data from union query for all schemas that uses the same union when string `resolveType` is provided\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class One {\n        @Field()\n        one!: string;\n      }\n      @ObjectType()\n      class Two {\n        @Field()\n        two!: string;\n      }\n      const OneTwo = createUnionType({\n        name: \"OneTwo\",\n        types: () => [One, Two],\n        resolveType: value => {\n          if (\"one\" in value) {\n            return \"One\";\n          }\n          if (\"two\" in value) {\n            return \"Two\";\n          }\n          throw new Error(\"Unknown union error\");\n        },\n      });\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => OneTwo)\n        oneTwo(): typeof OneTwo {\n          const one = new One();\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          oneTwo {\n            __typename\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should correctly return data from union query for all schemas that uses the same union when class `resolveType` is provided\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class One {\n        @Field()\n        one!: string;\n      }\n      @ObjectType()\n      class Two {\n        @Field()\n        two!: string;\n      }\n      const OneTwo = createUnionType({\n        name: \"OneTwo\",\n        types: () => [One, Two],\n        resolveType: value => {\n          if (\"one\" in value) {\n            return One;\n          }\n          if (\"two\" in value) {\n            return Two;\n          }\n          throw new Error(\"Unknown union error\");\n        },\n      });\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => OneTwo)\n        oneTwo(): typeof OneTwo {\n          const one = new One();\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          oneTwo {\n            __typename\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const firstSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const secondSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const firstResult = await graphql({ schema: firstSchema, source: query });\n      const secondResult = await graphql({ schema: secondSchema, source: query });\n\n      expect(firstResult.errors).toBeUndefined();\n      expect(firstResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n      expect(secondResult.errors).toBeUndefined();\n      expect(secondResult.data!.oneTwo).toEqual({\n        __typename: \"One\",\n        one: \"one\",\n      });\n    });\n\n    it(\"should should fail with error info when `resolveType` returns undefined\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class One {\n        @Field()\n        one!: string;\n      }\n      @ObjectType()\n      class Two {\n        @Field()\n        two!: string;\n      }\n      const OneTwo = createUnionType({\n        name: \"OneTwo\",\n        types: () => [One, Two],\n        resolveType: () => undefined,\n      });\n      @Resolver()\n      class OneTwoResolver {\n        @Query(() => OneTwo)\n        oneTwo(): typeof OneTwo {\n          const one = new One();\n          one.one = \"one\";\n          return one;\n        }\n      }\n      const query = /* graphql */ `\n        query {\n          oneTwo {\n            __typename\n            ... on One {\n              one\n            }\n            ... on Two {\n              two\n            }\n          }\n        }\n      `;\n\n      const testSchema = await buildSchema({\n        resolvers: [OneTwoResolver],\n      });\n      const result: any = await graphql({ schema: testSchema, source: query });\n\n      expect(result.errors?.[0]?.message).toMatchInlineSnapshot(\n        `\"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.\"`,\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "tests/functional/validation.ts",
    "content": "import \"reflect-metadata\";\nimport { Max, MaxLength, Min, ValidateNested } from \"class-validator\";\nimport { type GraphQLSchema, graphql } from \"graphql\";\nimport {\n  Arg,\n  Args,\n  ArgsType,\n  ArgumentValidationError,\n  Field,\n  InputType,\n  Mutation,\n  ObjectType,\n  Query,\n  Resolver,\n  type ResolverData,\n  buildSchema,\n  getMetadataStorage,\n} from \"type-graphql\";\nimport { type TypeValue } from \"@/decorators/types\";\n\ndescribe(\"Validation\", () => {\n  describe(\"Functional\", () => {\n    let schema: GraphQLSchema;\n    let argInput: any;\n    let argsData: any;\n\n    beforeEach(() => {\n      argInput = undefined;\n      argsData = undefined;\n    });\n\n    beforeAll(async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n\n      @InputType()\n      class SampleInput {\n        @Field()\n        @MaxLength(5)\n        stringField!: string;\n\n        @Field()\n        @Max(5)\n        numberField!: number;\n\n        @Field({ nullable: true })\n        @Min(5)\n        optionalField?: number;\n\n        @Field(() => SampleInput, { nullable: true })\n        @ValidateNested()\n        nestedField?: SampleInput;\n\n        @Field(() => [SampleInput], { nullable: true })\n        @ValidateNested({ each: true })\n        arrayField?: SampleInput[];\n      }\n\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5)\n        stringField!: string;\n\n        @Field()\n        @Max(5)\n        numberField!: number;\n\n        @Field({ nullable: true })\n        @Min(5)\n        optionalField?: number;\n      }\n\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args() args: SampleArguments): SampleObject {\n          argsData = args;\n          return {};\n        }\n\n        @Mutation()\n        sampleMutation(@Arg(\"input\") input: SampleInput): SampleObject {\n          argInput = input;\n          return {};\n        }\n\n        @Mutation()\n        mutationWithInputsArray(\n          @Arg(\"inputs\", () => [SampleInput]) inputs: SampleInput[],\n        ): SampleObject {\n          argInput = inputs;\n          return {};\n        }\n\n        @Mutation()\n        mutationWithOptionalInputsArray(\n          @Arg(\"inputs\", () => [SampleInput], { nullable: \"items\" })\n          inputs: Array<SampleInput | null>,\n        ): SampleObject {\n          argInput = inputs;\n          return {};\n        }\n      }\n\n      schema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: true,\n      });\n    });\n\n    it(\"should pass input validation when data without optional field is correct\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 5,\n        }) {\n          field\n        }\n      }`;\n      await graphql({ schema, source: mutation });\n\n      expect(argInput).toEqual({ stringField: \"12345\", numberField: 5 });\n    });\n\n    it(\"should pass input validation when data with optional field is correct\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 5,\n          optionalField: 5,\n        }) {\n          field\n        }\n      }`;\n      await graphql({ schema, source: mutation });\n\n      expect(argInput).toEqual({ stringField: \"12345\", numberField: 5, optionalField: 5 });\n    });\n\n    it(\"should throw validation error when input is incorrect\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 15,\n        }) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"numberField\");\n    });\n\n    it(\"should throw validation error when nested input field is incorrect\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 5,\n          nestedField: {\n            stringField: \"12345\",\n            numberField: 15,\n          }\n        }) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"nestedField\");\n    });\n\n    it(\"should throw validation error when nested array input field is incorrect\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 5,\n          arrayField: [{\n            stringField: \"12345\",\n            numberField: 15,\n          }]\n        }) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"arrayField\");\n    });\n\n    it(\"should throw validation error when one of input array is incorrect\", async () => {\n      const mutation = `mutation {\n        mutationWithInputsArray(inputs: [\n          {\n            stringField: \"12345\",\n            numberField: 5,\n          },\n          {\n            stringField: \"12345\",\n            numberField: 15,\n          },\n        ]) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"numberField\");\n    });\n\n    it(\"should not throw error when one of optional items in the input array is null\", async () => {\n      const mutation = `mutation {\n        mutationWithOptionalInputsArray(inputs: [\n          null,\n          {\n            stringField: \"12345\",\n            numberField: 5\n          },\n        ]) {\n          field\n        }\n      }`;\n\n      const result = await graphql({ schema, source: mutation });\n      expect(result.errors).toBeUndefined();\n      expect(result.data).toEqual({ mutationWithOptionalInputsArray: { field: null } });\n    });\n\n    it(\"should properly validate arg array when one of optional items in the input array is incorrect\", async () => {\n      const mutation = `mutation {\n        mutationWithOptionalInputsArray(inputs: [\n          null,\n          {\n            stringField: \"12345\",\n            numberField: 5\n          },\n          {\n            stringField: \"12345\",\n            numberField: 15,\n          },\n        ]) {\n          field\n        }\n      }`;\n\n      const result = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"numberField\");\n    });\n\n    it(\"should throw validation error when optional input field is incorrect\", async () => {\n      const mutation = `mutation {\n        sampleMutation(input: {\n          stringField: \"12345\",\n          numberField: 5,\n          optionalField: -5,\n        }) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: mutation });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"optionalField\");\n    });\n\n    it(\"should pass input validation when arguments data without optional field is correct\", async () => {\n      const query = `query {\n      sampleQuery(\n        stringField: \"12345\",\n        numberField: 5,\n      ) {\n        field\n      }\n    }`;\n      await graphql({ schema, source: query });\n\n      expect(argsData).toEqual({ stringField: \"12345\", numberField: 5 });\n    });\n\n    it(\"should pass input validation when arguments data with optional field is correct\", async () => {\n      const query = `query {\n        sampleQuery(\n          stringField: \"12345\",\n          numberField: 5,\n          optionalField: 5,\n        ) {\n          field\n        }\n      }`;\n      await graphql({ schema, source: query });\n\n      expect(argsData).toEqual({ stringField: \"12345\", numberField: 5, optionalField: 5 });\n    });\n\n    it(\"should throw validation error when one of arguments is incorrect\", async () => {\n      const query = `query {\n        sampleQuery(\n          stringField: \"12345\",\n          numberField: 15,\n        ) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"numberField\");\n    });\n\n    it(\"should throw validation error when optional argument is incorrect\", async () => {\n      const query = `query {\n        sampleQuery(\n          stringField: \"12345\",\n          numberField: 5,\n          optionalField: -5,\n        ) {\n          field\n        }\n      }`;\n\n      const result: any = await graphql({ schema, source: query });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"optionalField\");\n    });\n  });\n\n  describe(\"Settings\", () => {\n    let localArgsData: any;\n    beforeEach(() => {\n      localArgsData = undefined;\n    });\n\n    it(\"should pass incorrect args when validation is turned off by default\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5)\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args() args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        // default - `validate: false,`\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"12345678\",\n        ) {\n          field\n        }\n      }`;\n      await graphql({ schema: localSchema, source: query });\n      expect(localArgsData).toEqual({ field: \"12345678\" });\n    });\n\n    it(\"should pass incorrect args when validation is turned off explicitly\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5)\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args() args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"12345678\",\n        ) {\n          field\n        }\n      }`;\n      await graphql({ schema: localSchema, source: query });\n      expect(localArgsData).toEqual({ field: \"12345678\" });\n    });\n\n    it(\"should pass incorrect args when validation is locally turned off\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5)\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args({ validate: false }) args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: true,\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"12345678\",\n        ) {\n          field\n        }\n      }`;\n      await graphql({ schema: localSchema, source: query });\n      expect(localArgsData).toEqual({ field: \"12345678\" });\n    });\n\n    it(\"should throw validation error when validation is locally turned on\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5)\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args({ validate: true }) args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"12345678\",\n        ) {\n          field\n        }\n      }`;\n      const result: any = await graphql({ schema: localSchema, source: query });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"field\");\n    });\n\n    it(\"should throw validation error for incorrect args when applied local validation settings\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5, { groups: [\"test\"] })\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args({ validate: { groups: [\"test\"] } }) args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"12345678\",\n        ) {\n          field\n        }\n      }`;\n      const result: any = await graphql({ schema: localSchema, source: query });\n      expect(result.data).toBeNull();\n      expect(result.errors).toHaveLength(1);\n\n      const validationError = result.errors![0].originalError! as ArgumentValidationError;\n      expect(validationError).toBeInstanceOf(ArgumentValidationError);\n      expect(validationError.extensions.validationErrors).toHaveLength(1);\n      expect(validationError.extensions.validationErrors[0].property).toEqual(\"field\");\n    });\n\n    it(\"should pass validation of incorrect args when applied local validation settings\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5, { groups: [\"not-test\"] })\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args({ validate: { groups: [\"test\"] } }) args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: false,\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"123456789\",\n        ) {\n          field\n        }\n      }`;\n      await graphql({ schema: localSchema, source: query });\n      expect(localArgsData).toEqual({ field: \"123456789\" });\n    });\n\n    it(\"should merge local validation settings with global one\", async () => {\n      getMetadataStorage().clear();\n\n      @ObjectType()\n      class SampleObject {\n        @Field({ nullable: true })\n        field?: string;\n      }\n      @ArgsType()\n      class SampleArguments {\n        @Field()\n        @MaxLength(5, { groups: [\"test\"] })\n        field!: string;\n      }\n      @Resolver(() => SampleObject)\n      class SampleResolver {\n        @Query()\n        sampleQuery(@Args({ validate: { groups: [\"test\"] } }) args: SampleArguments): SampleObject {\n          localArgsData = args;\n          return {};\n        }\n      }\n      const localSchema = await buildSchema({\n        resolvers: [SampleResolver],\n        validate: { validationError: { target: false } },\n      });\n\n      const query = `query {\n        sampleQuery(\n          field: \"123456789\",\n        ) {\n          field\n        }\n      }`;\n      const { errors } = await graphql({ schema: localSchema, source: query });\n      const error = errors![0].originalError! as ArgumentValidationError;\n\n      expect(localArgsData).toBeUndefined();\n      expect(error.extensions.validationErrors[0].target).toBeUndefined();\n    });\n  });\n});\n\ndescribe(\"Custom validation\", () => {\n  let schema: GraphQLSchema;\n  const document = /* graphql */ `\n    query {\n      sampleQuery(sampleField: \"sampleFieldValue\")\n    }\n  `;\n  let sampleArgsCls: Function;\n  let sampleInputCls: Function;\n  let sampleResolverCls: Function;\n\n  let validateArgs: Array<any | undefined> = [];\n  let validateTypes: TypeValue[] = [];\n  let validateResolverData: ResolverData[] = [];\n  let sampleQueryArgs: any[] = [];\n\n  beforeEach(() => {\n    // Reset ALL shared state\n    getMetadataStorage().clear();\n    validateArgs = [];\n    validateTypes = [];\n    validateResolverData = [];\n    sampleQueryArgs = [];\n\n    @ArgsType()\n    class SampleArgs {\n      @Field()\n      sampleField!: string;\n    }\n    sampleArgsCls = SampleArgs;\n    @InputType()\n    class SampleInput {\n      @Field()\n      sampleField!: string;\n    }\n    sampleInputCls = SampleInput;\n    @Resolver()\n    class SampleResolver {\n      @Query(() => Boolean)\n      sampleQuery(@Args() args: SampleArgs) {\n        sampleQueryArgs.push(args);\n        return true;\n      }\n\n      @Query(() => Boolean)\n      sampleArrayArgQuery(@Arg(\"arrayArg\", () => [SampleInput]) arrayArg: SampleInput[]) {\n        sampleQueryArgs.push(arrayArg);\n        return true;\n      }\n\n      @Query()\n      sampleInlineArgValidateFnQuery(\n        @Arg(\"arg\", {\n          validateFn: (arg, type, resolverData) => {\n            validateArgs.push(arg);\n            validateTypes.push(type);\n            validateResolverData.push(resolverData);\n          },\n        })\n        arg: SampleInput,\n      ): string {\n        return arg.sampleField;\n      }\n    }\n    sampleResolverCls = SampleResolver;\n  });\n\n  it(\"should call `validateFn` function provided in option with proper params\", async () => {\n    schema = await buildSchema({\n      resolvers: [sampleResolverCls],\n      validateFn: (arg, type, resolverData) => {\n        validateArgs.push(arg);\n        validateTypes.push(type);\n        validateResolverData.push(resolverData);\n      },\n    });\n\n    await graphql({ schema, source: document, contextValue: { isContext: true } });\n\n    expect(validateArgs).toEqual([{ sampleField: \"sampleFieldValue\" }]);\n    expect(validateArgs[0]).toBeInstanceOf(sampleArgsCls);\n    expect(validateTypes).toEqual([sampleArgsCls]);\n    expect(validateResolverData).toEqual([\n      expect.objectContaining({\n        context: { isContext: true },\n      }),\n    ]);\n  });\n\n  it(\"should let `validateFn` function handle array args\", async () => {\n    schema = await buildSchema({\n      resolvers: [sampleResolverCls],\n      validateFn: (arg, type) => {\n        validateArgs.push(arg);\n        validateTypes.push(type);\n      },\n    });\n\n    await graphql({\n      schema,\n      source: /* graphql */ `\n        query {\n          sampleArrayArgQuery(arrayArg: [{ sampleField: \"sampleFieldValue\" }])\n        }\n      `,\n    });\n\n    expect(validateArgs).toEqual([[{ sampleField: \"sampleFieldValue\" }]]);\n    expect((validateArgs[0] as object[])[0]).toBeInstanceOf(sampleInputCls);\n    expect(validateTypes).toEqual([sampleInputCls]);\n  });\n\n  it(\"should inject validated arg as resolver param\", async () => {\n    schema = await buildSchema({\n      resolvers: [sampleResolverCls],\n      validateFn: () => {\n        // do nothing\n      },\n    });\n\n    await graphql({ schema, source: document });\n\n    expect(sampleQueryArgs).toEqual([{ sampleField: \"sampleFieldValue\" }]);\n  });\n\n  it(\"should call `validateFn` function provided inline in arg option with proper params\", async () => {\n    schema = await buildSchema({\n      resolvers: [sampleResolverCls],\n    });\n\n    await graphql({\n      schema,\n      source: /* graphql */ `\n        query {\n          sampleInlineArgValidateFnQuery(arg: { sampleField: \"sampleArgValue\" })\n        }\n      `,\n      contextValue: { isContext: true },\n    });\n\n    expect(validateArgs).toEqual([{ sampleField: \"sampleArgValue\" }]);\n    expect(validateArgs[0]).toBeInstanceOf(sampleInputCls);\n    expect(validateTypes).toEqual([sampleInputCls]);\n    expect(validateResolverData).toEqual([\n      expect.objectContaining({\n        context: { isContext: true },\n      }),\n    ]);\n  });\n\n  it(\"should rethrow wrapped error when error thrown in `validate`\", async () => {\n    schema = await buildSchema({\n      resolvers: [sampleResolverCls],\n      validateFn: () => {\n        throw new Error(\"Test validate error\");\n      },\n    });\n\n    const result: any = await graphql({ schema, source: document });\n\n    expect(result.errors).toHaveLength(1);\n    expect(result.errors![0].message).toEqual(\"Test validate error\");\n    expect(result.data).toBeNull();\n    expect(sampleQueryArgs).toHaveLength(0);\n  });\n});\n"
  },
  {
    "path": "tests/helpers/circular-refs/good/CircularRef1.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n// eslint-disable-next-line import/no-cycle\nimport { CircularRef2 } from \"./CircularRef2\";\n\nlet hasModuleFinishedInitialLoad = false;\n\n@ObjectType()\nexport class CircularRef1 {\n  @Field(() => {\n    if (!hasModuleFinishedInitialLoad) {\n      throw new Error(\"Field type function was called synchronously during module load\");\n    }\n    return [CircularRef2];\n  })\n  ref2Field!: any[];\n}\n\nhasModuleFinishedInitialLoad = true;\n"
  },
  {
    "path": "tests/helpers/circular-refs/good/CircularRef2.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n// eslint-disable-next-line import/no-cycle\nimport { CircularRef1 } from \"./CircularRef1\";\n\nlet hasModuleFinishedInitialLoad = false;\n\n@ObjectType()\nexport class CircularRef2 {\n  @Field(() => {\n    if (!hasModuleFinishedInitialLoad) {\n      throw new Error(\"Field type function was called synchronously during module load\");\n    }\n    return [CircularRef1];\n  })\n  ref1Field!: any[];\n}\n\nhasModuleFinishedInitialLoad = true;\n"
  },
  {
    "path": "tests/helpers/circular-refs/wrong/CircularRef1.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n// eslint-disable-next-line import/no-cycle\nimport { CircularRef2 } from \"./CircularRef2\";\n\n@ObjectType()\nexport class CircularRef1 {\n  @Field()\n  ref2Field!: CircularRef2;\n}\n"
  },
  {
    "path": "tests/helpers/circular-refs/wrong/CircularRef2.ts",
    "content": "import { Field, ObjectType } from \"type-graphql\";\n// eslint-disable-next-line import/no-cycle\nimport { CircularRef1 } from \"./CircularRef1\";\n\n@ObjectType()\nexport class CircularRef2 {\n  @Field()\n  ref1Field!: CircularRef1;\n}\n"
  },
  {
    "path": "tests/helpers/customScalar.ts",
    "content": "import { GraphQLScalarType } from \"graphql\";\n\nexport const CustomScalar = new GraphQLScalarType({\n  name: \"Custom\",\n  parseLiteral: () => \"TypeGraphQL parseLiteral\",\n  parseValue: () => \"TypeGraphQL parseValue\",\n  serialize: () => \"TypeGraphQL serialize\",\n});\n\nexport class CustomType {}\n\nexport const ObjectScalar = new GraphQLScalarType({\n  name: \"ObjectScalar\",\n  parseLiteral: () => ({\n    value: \"TypeGraphQL parseLiteral\",\n  }),\n  parseValue: () => ({\n    value: \"TypeGraphQL parseValue\",\n  }),\n  serialize: (obj: any) => obj.value,\n});\n"
  },
  {
    "path": "tests/helpers/directives/TestDirective.ts",
    "content": "import { MapperKind, getDirective, mapSchema } from \"@graphql-tools/utils\";\nimport {\n  DirectiveLocation,\n  type GraphQLArgumentConfig,\n  GraphQLDirective,\n  type GraphQLFieldConfig,\n  type GraphQLInputFieldConfig,\n  GraphQLInputObjectType,\n  type GraphQLInputObjectTypeConfig,\n  GraphQLInterfaceType,\n  type GraphQLInterfaceTypeConfig,\n  GraphQLNonNull,\n  GraphQLObjectType,\n  type GraphQLObjectTypeConfig,\n  type GraphQLSchema,\n  GraphQLString,\n} from \"graphql\";\n\nfunction mapConfig<\n  TConfig extends\n    | GraphQLFieldConfig<any, any, any>\n    | GraphQLObjectTypeConfig<any, any>\n    | GraphQLInterfaceTypeConfig<any, any>\n    | GraphQLInputObjectTypeConfig\n    | GraphQLInputFieldConfig\n    | GraphQLArgumentConfig,\n>(config: TConfig) {\n  return {\n    ...config,\n    extensions: {\n      ...config.extensions,\n      TypeGraphQL: {\n        isMappedByDirective: true,\n      },\n    },\n  };\n}\n\nexport const testDirective = new GraphQLDirective({\n  name: \"test\",\n  args: {\n    argNonNullDefault: {\n      type: new GraphQLNonNull(GraphQLString),\n      defaultValue: \"argNonNullDefault\",\n    },\n    argNullDefault: {\n      type: GraphQLString,\n      defaultValue: \"argNullDefault\",\n    },\n    argNull: {\n      type: GraphQLString,\n    },\n  },\n  locations: [\n    DirectiveLocation.OBJECT,\n    DirectiveLocation.FIELD_DEFINITION,\n    DirectiveLocation.INPUT_OBJECT,\n    DirectiveLocation.INPUT_FIELD_DEFINITION,\n    DirectiveLocation.INTERFACE,\n    DirectiveLocation.ARGUMENT_DEFINITION,\n  ],\n});\n\nexport function testDirectiveTransformer(schema: GraphQLSchema): GraphQLSchema {\n  return mapSchema(schema, {\n    [MapperKind.OBJECT_TYPE]: typeInfo => {\n      const testDirectiveConfig = getDirective(schema, typeInfo, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        const config = typeInfo.toConfig();\n        return new GraphQLObjectType(mapConfig(config));\n      }\n      return typeInfo;\n    },\n    [MapperKind.OBJECT_FIELD]: fieldConfig => {\n      const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        return mapConfig(fieldConfig);\n      }\n      return fieldConfig;\n    },\n    [MapperKind.INTERFACE_TYPE]: interfaceConfig => {\n      const testDirectiveConfig = getDirective(schema, interfaceConfig, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        const config = interfaceConfig.toConfig();\n        return new GraphQLInterfaceType(mapConfig(config));\n      }\n      return interfaceConfig;\n    },\n    [MapperKind.INTERFACE_FIELD]: fieldConfig => {\n      const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        return mapConfig(fieldConfig);\n      }\n      return fieldConfig;\n    },\n    [MapperKind.INPUT_OBJECT_TYPE]: typeInfo => {\n      const testDirectiveConfig = getDirective(schema, typeInfo, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        const config = typeInfo.toConfig();\n        return new GraphQLInputObjectType(mapConfig(config));\n      }\n      return typeInfo;\n    },\n    [MapperKind.INPUT_OBJECT_FIELD]: fieldConfig => {\n      const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        return mapConfig(fieldConfig);\n      }\n      return fieldConfig;\n    },\n    [MapperKind.ARGUMENT]: argumentConfig => {\n      const testDirectiveConfig = getDirective(schema, argumentConfig, testDirective.name)?.[0];\n      if (testDirectiveConfig) {\n        return mapConfig(argumentConfig);\n      }\n      return argumentConfig;\n    },\n  });\n}\n"
  },
  {
    "path": "tests/helpers/directives/assertValidDirective.ts",
    "content": "import {\n  type FieldDefinitionNode,\n  type InputObjectTypeDefinitionNode,\n  type InputValueDefinitionNode,\n  type InterfaceTypeDefinitionNode,\n  type ObjectTypeDefinitionNode,\n  parseValue,\n} from \"graphql\";\nimport { type Maybe } from \"@/typings\";\n\nexport function assertValidDirective(\n  astNode: Maybe<\n    | FieldDefinitionNode\n    | ObjectTypeDefinitionNode\n    | InputObjectTypeDefinitionNode\n    | InputValueDefinitionNode\n    | InterfaceTypeDefinitionNode\n  >,\n  name: string,\n  args?: Record<string, string>,\n): void {\n  if (!astNode) {\n    throw new Error(`Directive with name ${name} does not exist`);\n  }\n\n  const directives = (astNode && astNode.directives) || [];\n\n  const directive = directives.find(it => it.name.kind === \"Name\" && it.name.value === name);\n\n  if (!directive) {\n    throw new Error(`Directive with name ${name} does not exist`);\n  }\n\n  if (!args) {\n    if (Array.isArray(directive.arguments)) {\n      expect(directive.arguments).toHaveLength(0);\n    } else {\n      expect(directive.arguments).toBeFalsy();\n    }\n  } else {\n    expect(directive.arguments).toHaveLength(Object.keys(args).length);\n    expect(directive.arguments).toEqual(\n      expect.arrayContaining(\n        Object.keys(args).map(arg =>\n          expect.objectContaining({\n            kind: \"Argument\",\n            name: expect.objectContaining({ kind: \"Name\", value: arg }),\n            value: expect.objectContaining(parseValue(args[arg], { noLocation: true })),\n          }),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "tests/helpers/expectToThrow.ts",
    "content": "export async function expectToThrow<TError extends Error>(call: () => unknown): Promise<TError> {\n  try {\n    await call();\n  } catch (error: unknown) {\n    return error as TError;\n  }\n\n  throw new Error(\"You've expected a function to throw, but it didn't throw anything.\");\n}\n"
  },
  {
    "path": "tests/helpers/getInnerFieldType.ts",
    "content": "import {\n  type IntrospectionInputObjectType,\n  type IntrospectionInterfaceType,\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionTypeRef,\n} from \"graphql\";\n\nexport function getInnerTypeOfNonNullableType(definition: { type: IntrospectionTypeRef }) {\n  return (definition.type as IntrospectionNonNullTypeRef).ofType! as IntrospectionNamedTypeRef;\n}\n\nexport function getInnerFieldType(\n  type: IntrospectionObjectType | IntrospectionInterfaceType,\n  name: string,\n) {\n  return getInnerTypeOfNonNullableType(type.fields.find(field => field.name === name)!);\n}\n\nexport function getInnerInputFieldType(type: IntrospectionInputObjectType, name: string) {\n  return getInnerTypeOfNonNullableType(type.inputFields.find(field => field.name === name)!);\n}\n\nexport function getItemTypeOfList(definition: { type: IntrospectionTypeRef }) {\n  const listType = (definition.type as IntrospectionNonNullTypeRef)\n    .ofType! as IntrospectionNonNullTypeRef;\n  const itemType = (listType.ofType! as IntrospectionNonNullTypeRef)\n    .ofType as IntrospectionNamedTypeRef;\n  return itemType;\n}\n"
  },
  {
    "path": "tests/helpers/getSampleObjectFieldType.ts",
    "content": "import {\n  type IntrospectionNamedTypeRef,\n  type IntrospectionNonNullTypeRef,\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n} from \"graphql\";\n\nexport function getSampleObjectFieldType(schemaIntrospection: IntrospectionSchema) {\n  const sampleObject = schemaIntrospection.types.find(\n    type => type.name === \"SampleObject\",\n  ) as IntrospectionObjectType;\n  return (fieldName: string) => {\n    const field = sampleObject.fields.find(it => it.name === fieldName)!;\n    const fieldType = (field.type as IntrospectionNonNullTypeRef)\n      .ofType as IntrospectionNamedTypeRef;\n    return fieldType;\n  };\n}\n"
  },
  {
    "path": "tests/helpers/getSchemaInfo.ts",
    "content": "/* eslint \"no-underscore-dangle\": [\"error\", { \"allow\": [\"__schema\"] }] */\nimport {\n  type IntrospectionObjectType,\n  type IntrospectionSchema,\n  getIntrospectionQuery,\n  graphql,\n} from \"graphql\";\nimport { type BuildSchemaOptions, buildSchema } from \"type-graphql\";\n\nexport async function getSchemaInfo(options: BuildSchemaOptions) {\n  // Build schema from definitions\n  const schema = await buildSchema({\n    ...options,\n    validate: false,\n    skipCheck: true,\n  });\n\n  // Get built schema info from retrospection\n  const result = await graphql({\n    schema,\n    source: getIntrospectionQuery({\n      inputValueDeprecation: true,\n    }),\n  });\n  expect(result.errors).toBeUndefined();\n\n  const schemaIntrospection = result.data!.__schema as IntrospectionSchema;\n  expect(schemaIntrospection).toBeDefined();\n\n  const queryType = schemaIntrospection.types.find(\n    type => type.name === schemaIntrospection.queryType.name,\n  ) as IntrospectionObjectType;\n\n  const mutationTypeNameRef = schemaIntrospection.mutationType;\n  let mutationType: IntrospectionObjectType | undefined;\n  if (mutationTypeNameRef) {\n    mutationType = schemaIntrospection.types.find(\n      type => type.name === mutationTypeNameRef.name,\n    ) as IntrospectionObjectType;\n  }\n\n  const subscriptionTypeNameRef = schemaIntrospection.subscriptionType;\n  let subscriptionType: IntrospectionObjectType | undefined;\n  if (subscriptionTypeNameRef) {\n    subscriptionType = schemaIntrospection.types.find(\n      type => type.name === subscriptionTypeNameRef.name,\n    ) as IntrospectionObjectType;\n  }\n\n  return {\n    schema,\n    schemaIntrospection,\n    queryType,\n    mutationType,\n    subscriptionType,\n  };\n}\n"
  },
  {
    "path": "tests/helpers/getTypeField.ts",
    "content": "import {\n  type IntrospectionField,\n  type IntrospectionInterfaceType,\n  type IntrospectionObjectType,\n} from \"graphql\";\n\nexport function getTypeField(\n  type: IntrospectionObjectType | IntrospectionInterfaceType,\n  fieldName: string,\n): IntrospectionField {\n  return type.fields.find(field => field.name === fieldName)!;\n}\n"
  },
  {
    "path": "tests/helpers/sleep.ts",
    "content": "export function sleep(ms: number): Promise<void> {\n  return new Promise(resolve => {\n    setTimeout(resolve, ms);\n  });\n}\n"
  },
  {
    "path": "tests/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"noEmit\": true,\n    \"noUnusedLocals\": false,\n    \"emitDecoratorMetadata\": true\n  },\n  \"include\": [\".\", \"../src\"]\n}\n"
  },
  {
    "path": "tsconfig.cjs.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"outDir\": \"./build/cjs\"\n  }\n}\n"
  },
  {
    "path": "tsconfig.esm.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"es2020\",\n    \"moduleResolution\": \"bundler\",\n    \"outDir\": \"./build/esm\"\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"commonjs\",\n    \"declaration\": false,\n    \"sourceMap\": false,\n    \"outDir\": \"./build\",\n    \"moduleResolution\": \"node\",\n    \"removeComments\": true,\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"allowUnreachableCode\": false,\n    \"allowUnusedLabels\": false,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"skipLibCheck\": true,\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": false,\n    \"resolveJsonModule\": true,\n    \"plugins\": [\n      {\n        \"transform\": \"typescript-transform-paths\"\n      },\n      {\n        \"transform\": \"typescript-transform-paths\",\n        \"afterDeclarations\": true\n      },\n      {\n        \"transform\": \"typescript-transformer-esm\",\n        \"after\": true\n      },\n      {\n        \"transform\": \"typescript-transformer-esm\",\n        \"afterDeclarations\": true\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\"./src/*\"],\n      \"type-graphql\": [\"./src/index.ts\"]\n    }\n  },\n  \"exclude\": [\"./node_modules\", \"./build\"],\n  \"include\": [\"./src\"]\n}\n"
  },
  {
    "path": "tsconfig.typings.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./build/typings\",\n    \"emitDeclarationOnly\": true,\n    \"declaration\": true,\n    \"removeComments\": false\n  }\n}\n"
  },
  {
    "path": "website/.gitignore",
    "content": "node_modules\n.DS_Store\nlib/core/metadata.js\nlib/core/MetadataBlog.js\nwebsite/translated_docs\nwebsite/build/\nwebsite/yarn.lock\nwebsite/node_modules\n\nwebsite/i18n/*\n!website/i18n/en.json\n"
  },
  {
    "path": "website/blog/2018-03-25-medium-article.md",
    "content": "---\ntitle: GraphQL + TypeScript = TypeGraphQL\nauthor: Michał Lytek\nauthorURL: https://github.com/MichalLytek\nauthorImageURL: /img/author.jpg\n---\n\nWe all love GraphQL! It’s so great and solves many problems that we have with REST API, like overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of pain.\n\n**TypeGraphQL** makes that process enjoyable, i.a. by defining the schema using only classes and a bit of decorators magic.\n\n<!--truncate-->\n\n![type-graphql-logo](/blog/assets/logo_mini.png)\n\n## Motivation\n\nAs 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.\n\nAt 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.:\n\n```typescript\nexport const recipesResolver: GraphQLFieldResolver<void, Context, RecipesArgs> = async (\n  _,\n  args,\n) => {\n  // stuffs like validation, auth checking, getting from container\n  // and our business logic, e.g.:\n  const repository = getRepository(Recipe);\n  return repository.find();\n};\n```\n\nThe 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.\n\n**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.\n\n## Getting started\n\nTo explore all powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet’s start with the Recipe type, which is the foundations of our API.\nWe want to get equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the Recipe class with all properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we annotate the class and it properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe 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).\n\n### Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe 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).\n\n### Inputs and arguments\n\nOk, but what are theNewRecipeInput and RecipesArgs? There are of course classes that declares input type and arguments:\n\n```typescript\n@InputType()\nclass NewRecipeDataInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @MaxArraySize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int, { nullable: true })\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int, { nullable: true })\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` or `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform fields validation in TypeGraphQL.\n\n### Building schema\n\nThe last step that we have to do is to actually build the schema from TypeGraphQL definition. We use buildSchema function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully working GraphQL schema! If we print it, we would receive exactly this:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int, take: Int): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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!\n\nIf 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).\n\n## Work in progress\n\nCurrently 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).\n\nThere 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).\n\n## Spread the word\n\nI strongly encourage you to give it a try and experiment with **TypeGraphQL**.\nI promise, it will reduce your codebase by a half or more!\n\nIf you find this framework interesting, please [star the GitHub repository](https://github.com/MichalLytek/type-graphql), clap for this article and share it on your social media, if you don’t mind.\n\nThe more feedback I receive, the more time I will devote to continue the development of TypeGraphQL!\n"
  },
  {
    "path": "website/blog/2020-08-19-devto-article.md",
    "content": "---\ntitle: Announcing TypeGraphQL 1.0 🚀\nauthor: Michał Lytek\nauthorURL: https://github.com/MichalLytek\nauthorImageURL: /img/author.jpg\n---\n\nIt's finally happening! Over two years after the [initial announcement](http://localhost:3000/blog/2018/03/25/medium-article.html), [TypeGraphQL](https://typegraphql.com/) is now ready for its first stable release - `v1.0.0` 🎉\n\nIt was a really long journey that started in 31st of January 2018 with [releasing `v0.1.0`](https://www.npmjs.com/package/type-graphql/v/0.1.0) and which contained 650+ commits, 85+ merged PRs and [4.9k+ stars on GitHub](https://github.com/MichalLytek/type-graphql).\n\nThis post is focused mostly on presenting new features and describing changes in the newest stable release. Well, then, without further ado... let's take a look what the TypeGraphQL 1.0 brings us!\n\n- [Performance](#performance)\n- [Schema isolation](#isolation)\n- [Directives and extensions](#directives-extensions)\n- [Resolvers and arguments for interface fields](#interfaces)\n- [More descriptive errors messages](#errors)\n- [Transforming nested inputs and arrays](#transforming)\n- [...and others 👀](#others)\n\n<!--truncate-->\n\n## Performance <a name=\"performance\"></a>\n\nOne 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 ⚡\n\nTypeGraphQL 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.\n\nIt 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!\n\n| library             | execution time |\n| ------------------- | :------------: |\n| TypeGraphQL `v0.17` |   1253.28 ms   |\n| `graphql-js`        |   265.52 ms    |\n\nAfter 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%:\n\n|                          | execution time |\n| ------------------------ | :------------: |\n| `graphql-js`             |   265.52 ms    |\n| **TypeGraphQL `v1.0`**   |   310.36 ms    |\n| with \"simpleResolvers\"   |   299.61 ms    |\n| with a global middleware |   1267.82 ms   |\n\nSuch small overhead is much easier to accept than the initial 500%!\nMore 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).\n\n## Schema isolation <a name=\"isolation\"></a>\n\nThis is another feature that is not visible from the first sight but gives new possibilities like splitting the schema to public and private ones 👀\n\nIn 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.\n\nIn TypeGraphQL 1.0 it's no longer true!\nThe 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.\n\n```ts\nconst firstSchema = await buildSchema({\n  resolvers: [FirstResolver],\n});\nconst secondSchema = await buildSchema({\n  resolvers: [SecondResolver],\n});\n```\n\nSo just by modifying the `resolvers` option we can have different sets of operations exposed in the GraphQL schemas!\nProper isolation also makes serverless development easier as it allows to get rid of the _\"Schema must contain uniquely named types\"_ errors and others.\n\n## Directives and extensions <a name=\"directives-extensions\"></a>\n\nThis two new features are two complementary ways to put some metadata about the schema items.\n\nGraphQL directives though the syntax might remind the TS decorators, as \"a directive is an identifier preceded by a @ character\", but in fact, they are a purely Schema Definition Language feature. Apart from the metadata capabilities, they can also modify the schema and e.g. generate the connection type for pagination purposes. Basically, the looks like this:\n\n```graphql\ntype Query {\n  foobar: String! @auth(requires: USER)\n}\n```\n\nTo apply them, we just need to put the `@Directive` decorator above and supply the string argument, e.g.:\n\n```ts\n@Resolver()\nclass FooBarResolver {\n  @Directive(\"@auth(requires: USER)\")\n  @Query()\n  foobar(): string {\n    return \"foobar\";\n  }\n}\n```\n\nHowever, 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.\n\nTo declare the extensions for type or selected field, we need to use `@Extensions` decorator, e.g.:\n\n```ts\n@ObjectType()\nclass Foo {\n  @Extensions({ roles: [Role.User] })\n  @Field()\n  bar: string;\n}\n```\n\nWe can then read that metadata in the resolvers or middlewares, just by exploring the `GraphQLResolveInfo` object, e.g.:\n\n```ts\nexport const ExtensionsMiddleware: MiddlewareFn = async ({ info }, next) => {\n  const { extensions } = info.parentType.getFields()[info.fieldName];\n  console.log(extensions?.roles); // log the metadata\n  return next();\n};\n```\n\nMore info about [directives](https://typegraphql.com/docs/directives.html) and [extensions](https://typegraphql.com/docs/extensions.html) features can be found in docs 📖\n\n## Resolvers and arguments for interface fields <a name=\"interfaces\"></a>\n\nThe last thing that was preventing TypeGraphQL from being fully GraphQL compliant thus blocking the 1.0 release - an ability to provide interface fields resolvers implementations and declare its arguments.\n\nBasically, we can define resolvers for the interface fields using the same syntax we would use in case of the `@ObjectType`, e.g.:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\n...with only a few exceptions for cases like abstract methods and inheritance, which you can [read about in the docs](https://typegraphql.com/docs/interfaces.html#resolvers-and-arguments).\n\n## More descriptive errors messages <a name=\"errors\"></a>\n\nOne 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.\n\nMessages 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.\n\nNow, when the error occurs, it is broadly explained, why it happened and what could we do to fix that, e.g.:\n\n```text\nUnable to infer GraphQL type from TypeScript reflection system.\n  You need to provide explicit type for argument named 'filter'\n  of 'getUsers' of 'UserResolver' class.\n```\n\nor:\n\n```text\nSome errors occurred while generating GraphQL schema:\n  Interface field 'IUser.accountBalance' expects type 'String!'\n  but 'Student.accountBalance' is of type 'Float'\n```\n\nThat should allow developers to safe tons of time and really speed up the development 🏎\n\n## Transforming nested inputs and arrays <a name=\"transforming\"></a>\n\nIn the previous releases, an instance of the input type class was created only on the first level of inputs nesting.\nSo, in cases like this:\n\n```ts\n@InputType()\nclass SampleInput {\n  @Field()\n  sampleStringField: string;\n\n  @Field()\n  nestedField: SomeNestedInput;\n}\n\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(@Arg(\"input\") input: SampleInput): boolean {\n    return input.nestedField instanceof SomeNestedInput;\n  }\n}\n```\n\nthe `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).\n\nSince 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 💪\n\n## One more thing... <a name=\"others\"></a>\n\nThe 1.0 release is not our last word! We have plenty of feature requests from the community and [tons of our ideas to implement](https://github.com/MichalLytek/type-graphql/labels/Enhancement%20%3Anew%3A), so stay tuned and wait for more! 💪\n\nAlso, please keep in mind that TypeGraphQL is an MIT-licensed open source project. It doesn't have a large company that sits behind - its ongoing development is possible only thanks to the support by the community.\n\n[![GitHub Sponsors](https://dev-to-uploads.s3.amazonaws.com/i/5hylzjhbjte7lq8ev7gf.png)](https://github.com/sponsors/TypeGraphQL)\n\n[![Open Collective](https://opencollective.com/typegraphql/donate/button.png?color=blue)](https://opencollective.com/typegraphql)\n\nIf you fell in love with TypeGraphQL, please consider supporting our efforts and help it grow, especially if you are using it commercially - just to ensure that the project which your product relies on is actively maintained and improved.\n"
  },
  {
    "path": "website/core/Footer.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require(\"react\");\n\nconst toggleButtonHtml = /* html */ `\n  <div class=\"toggle\">\n    <span>🌙</span>\n    <input type=\"checkbox\" id=\"toggle-switch\" />\n    <label for=\"toggle-switch\">\n      <span class=\"screen-reader-text\">Toggle Color Scheme</span>\n    </label>\n    <span>☀️</span>\n  </div>`;\n\nconst DarkModeButton = () => {\n  return (\n    <>\n      <script\n        dangerouslySetInnerHTML={{\n          __html: /* js */ `\n            const html = document.querySelector(\"html\");\n\n            function appendButtonToDOM() {\n              const li = document.createElement(\"li\");\n              li.classList.add(\"center-list-item\");\n              li.innerHTML = '${toggleButtonHtml\n                .split(\"\\n\")\n                .map(it => it.trim())\n                .join(\"\")}';\n\n              const nav = document.querySelector(\".nav-site\");\n              nav.insertBefore(li, document.querySelector(\".navSearchWrapper\"));\n\n              const btn = document.querySelector(\"#toggle-switch\");\n              btn.addEventListener(\"click\", () => {\n                toggleColorMode();\n              });\n            }\n\n            function setInitialColorMode() {\n              const btn = document.querySelector(\"#toggle-switch\");\n              let currentColorMode = localStorage.getItem(\"theme\");\n\n              // button was never used\n              if (currentColorMode === null) {\n                // inspects OS preferred color scheme\n                if (\n                  window.matchMedia &&\n                  window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n                ) {\n                  currentColorMode = \"dark\";\n                } else {\n                  currentColorMode = \"light\";\n                }\n              }\n\n              if (currentColorMode === \"dark\") {\n                html.classList.add(\"theme-mode--dark\");\n                btn.checked = false;\n              } else {\n                html.classList.add(\"theme-mode--light\");\n                btn.checked = true;\n              }\n            }\n\n            function toggleColorMode() {\n              const btn = document.querySelector(\"#toggle-switch\");\n              localStorage.setItem(\"theme\", btn.checked ? \"light\" : \"dark\");\n              html.classList.toggle(\"theme-mode--dark\");\n              html.classList.toggle(\"theme-mode--light\");\n            }\n\n            appendButtonToDOM();\n            setInitialColorMode();\n          `,\n        }}\n      />\n    </>\n  );\n};\n\nclass Footer extends React.Component {\n  docUrl(doc, language) {\n    const baseUrl = this.props.config.baseUrl;\n    return baseUrl + \"docs/\" + (language ? language + \"/\" : \"\") + doc;\n  }\n\n  pageUrl(doc, language) {\n    const baseUrl = this.props.config.baseUrl;\n    return baseUrl + (language ? language + \"/\" : \"\") + doc;\n  }\n\n  render() {\n    const currentYear = new Date().getFullYear();\n    return (\n      <footer className=\"nav-footer\" id=\"footer\">\n        <DarkModeButton />\n        <section className=\"sitemap\">\n          <a href={this.props.config.baseUrl} className=\"nav-home\">\n            {this.props.config.footerIcon && (\n              <img\n                src={this.props.config.baseUrl + this.props.config.footerIcon}\n                alt={this.props.config.title}\n                width=\"66\"\n                height=\"58\"\n              />\n            )}\n          </a>\n          <div>\n            <h5>Docs</h5>\n            <a href={this.docUrl(\"introduction.html\")}>Introduction</a>\n            <a href={this.docUrl(\"getting-started.html\")}>Getting Started</a>\n            <a href={this.docUrl(\"scalars.html\")}>Advanced Guides</a>\n            <a href={this.docUrl(\"dependency-injection.html\")}>Features</a>\n            <a href={this.docUrl(\"emit-schema.html\")}>Others</a>\n            {/* <a href={this.docUrl('api.html')}>\n              API Reference\n            </a> */}\n          </div>\n          <div>\n            <h5>Community</h5>\n            {/* <a href={this.pageUrl('users.html')}>\n              User Showcase\n            </a> */}\n            {/* <a\n              href=\"http://stackoverflow.com/questions/tagged/type-graphql\"\n              target=\"_blank\">\n              Stack Overflow\n            </a> */}\n            <a\n              href={\n                this.props.config.repoUrl +\n                '/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A\"Enhancement+%3Anew%3A\"'\n              }\n              target=\"_blank\"\n            >\n              Feature requests and proposals\n            </a>\n            <a\n              href={\n                this.props.config.repoUrl +\n                '/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A\"Bug+%3Abug%3A\"'\n              }\n              target=\"_blank\"\n            >\n              Issues\n            </a>\n            <a href=\"https://twitter.com/typegraphql\" target=\"_blank\">\n              Twitter\n            </a>\n            <a href=\"https://opencollective.com/typegraphql\" target=\"_blank\">\n              Open Collective\n            </a>\n          </div>\n          <div>\n            <h5>More</h5>\n            <a href={this.props.config.baseUrl + \"blog\"}>Blog</a>\n            <a href={this.props.config.repoUrl} target=\"_blank\">\n              GitHub\n            </a>\n            <a\n              className=\"github-button\"\n              href={this.props.config.repoUrl}\n              data-icon=\"octicon-star\"\n              data-count-href=\"/facebook/docusaurus/stargazers\"\n              data-show-count={true}\n              data-count-aria-label=\"# stargazers on GitHub\"\n              aria-label=\"Star this project on GitHub\"\n            >\n              Star\n            </a>\n          </div>\n        </section>\n        <section className=\"copyright\">{this.props.config.copyright}</section>\n      </footer>\n    );\n  }\n}\n\nmodule.exports = Footer;\n"
  },
  {
    "path": "website/i18n/en.json",
    "content": "{\n  \"_comment\": \"This file is auto-generated by write-translations.js\",\n  \"localized-strings\": {\n    \"next\": \"Next\",\n    \"previous\": \"Previous\",\n    \"tagline\": \"Modern framework for GraphQL API in Node.js\",\n    \"docs\": {\n      \"authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"aws-lambda\": {\n        \"title\": \"AWS Lambda integration\"\n      },\n      \"azure-functions\": {\n        \"title\": \"Azure Functions Integration\"\n      },\n      \"bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"directives\": {\n        \"title\": \"Directives\"\n      },\n      \"emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"enums\": {\n        \"title\": \"Enums\"\n      },\n      \"esm\": {\n        \"title\": \"ECMAScript Modules\"\n      },\n      \"examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"installation\": {\n        \"title\": \"Installation\"\n      },\n      \"interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"migration-guide\": {\n        \"title\": \"Migration Guide\",\n        \"sidebar_label\": \"v1.x -> v2.0\"\n      },\n      \"nestjs\": {\n        \"title\": \"NestJS Integration\",\n        \"sidebar_label\": \"NestJS\"\n      },\n      \"performance\": {\n        \"title\": \"Performance\"\n      },\n      \"prisma\": {\n        \"title\": \"Prisma Integration\",\n        \"sidebar_label\": \"Prisma\"\n      },\n      \"README\": {\n        \"title\": \"README\"\n      },\n      \"resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"unions\": {\n        \"title\": \"Unions\"\n      },\n      \"validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-0.16.0/version-0.16.0-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-0.16.0/version-0.16.0-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-0.16.0/version-0.16.0-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-0.16.0/version-0.16.0-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-0.16.0/version-0.16.0-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-0.16.0/version-0.16.0-emit-schema\": {\n        \"title\": \"Emitting schema SDL\"\n      },\n      \"version-0.16.0/version-0.16.0-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-0.16.0/version-0.16.0-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.16.0/version-0.16.0-faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"version-0.16.0/version-0.16.0-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-0.16.0/version-0.16.0-interfaces-and-inheritance\": {\n        \"title\": \"Interfaces and inheritance\"\n      },\n      \"version-0.16.0/version-0.16.0-introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"version-0.16.0/version-0.16.0-middlewares\": {\n        \"title\": \"Middlewares and guards\"\n      },\n      \"version-0.16.0/version-0.16.0-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-0.16.0/version-0.16.0-scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"version-0.16.0/version-0.16.0-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-0.16.0/version-0.16.0-types-and-fields\": {\n        \"title\": \"Types and fields\"\n      },\n      \"version-0.16.0/version-0.16.0-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.16.0/version-0.16.0-validation\": {\n        \"title\": \"Arguments and inputs validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-0.17.0/version-0.17.0-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-0.17.0/version-0.17.0-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-0.17.0/version-0.17.0-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-0.17.0/version-0.17.0-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-0.17.0/version-0.17.0-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-0.17.0/version-0.17.0-emit-schema\": {\n        \"title\": \"Emitting schema SDL\"\n      },\n      \"version-0.17.0/version-0.17.0-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-0.17.0/version-0.17.0-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.17.0/version-0.17.0-faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"version-0.17.0/version-0.17.0-generic-types\": {\n        \"title\": \"Generic types\"\n      },\n      \"version-0.17.0/version-0.17.0-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-0.17.0/version-0.17.0-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-0.17.0/version-0.17.0-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-0.17.0/version-0.17.0-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-0.17.0/version-0.17.0-introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"version-0.17.0/version-0.17.0-middlewares\": {\n        \"title\": \"Middlewares and guards\"\n      },\n      \"version-0.17.0/version-0.17.0-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-0.17.0/version-0.17.0-scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"version-0.17.0/version-0.17.0-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-0.17.0/version-0.17.0-types-and-fields\": {\n        \"title\": \"Types and fields\"\n      },\n      \"version-0.17.0/version-0.17.0-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.17.0/version-0.17.0-validation\": {\n        \"title\": \"Arguments and inputs validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-0.17.1/version-0.17.1-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-0.17.1/version-0.17.1-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-0.17.1/version-0.17.1-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-0.17.1/version-0.17.1-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-0.17.1/version-0.17.1-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-0.17.1/version-0.17.1-emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"version-0.17.1/version-0.17.1-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-0.17.1/version-0.17.1-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.17.1/version-0.17.1-faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"version-0.17.1/version-0.17.1-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-0.17.1/version-0.17.1-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-0.17.1/version-0.17.1-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-0.17.1/version-0.17.1-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-0.17.1/version-0.17.1-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-0.17.1/version-0.17.1-introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"version-0.17.1/version-0.17.1-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-0.17.1/version-0.17.1-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-0.17.1/version-0.17.1-scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"version-0.17.1/version-0.17.1-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-0.17.1/version-0.17.1-types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"version-0.17.1/version-0.17.1-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.17.1/version-0.17.1-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-0.17.2/version-0.17.2-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.17.2/version-0.17.2-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-0.17.2/version-0.17.2-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-0.17.2/version-0.17.2-introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"version-0.17.2/version-0.17.2-types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"version-0.17.2/version-0.17.2-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.17.4/version-0.17.4-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-0.17.4/version-0.17.4-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.17.4/version-0.17.4-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-0.17.4/version-0.17.4-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-0.17.4/version-0.17.4-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-0.17.4/version-0.17.4-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.17.5/version-0.17.5-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-0.17.5/version-0.17.5-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-0.17.5/version-0.17.5-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-0.17.5/version-0.17.5-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-0.17.5/version-0.17.5-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-0.17.5/version-0.17.5-faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"version-0.17.5/version-0.17.5-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-0.17.5/version-0.17.5-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-0.17.5/version-0.17.5-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-0.17.5/version-0.17.5-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-0.17.5/version-0.17.5-types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"version-0.17.5/version-0.17.5-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-0.17.6/version-0.17.6-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-1.0.0/version-1.0.0-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-1.0.0/version-1.0.0-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-1.0.0/version-1.0.0-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-1.0.0/version-1.0.0-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-1.0.0/version-1.0.0-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-1.0.0/version-1.0.0-directives\": {\n        \"title\": \"Directives\"\n      },\n      \"version-1.0.0/version-1.0.0-emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"version-1.0.0/version-1.0.0-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-1.0.0/version-1.0.0-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-1.0.0/version-1.0.0-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-1.0.0/version-1.0.0-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-1.0.0/version-1.0.0-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-1.0.0/version-1.0.0-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-1.0.0/version-1.0.0-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-1.0.0/version-1.0.0-nestjs\": {\n        \"title\": \"NestJS Integration\",\n        \"sidebar_label\": \"NestJS\"\n      },\n      \"version-1.0.0/version-1.0.0-performance\": {\n        \"title\": \"Performance\"\n      },\n      \"version-1.0.0/version-1.0.0-prisma\": {\n        \"title\": \"Prisma Integration\",\n        \"sidebar_label\": \"Prisma\"\n      },\n      \"version-1.0.0/version-1.0.0-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-1.0.0/version-1.0.0-scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"version-1.0.0/version-1.0.0-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-1.0.0/version-1.0.0-types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"version-1.0.0/version-1.0.0-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-1.0.0/version-1.0.0-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-1.1.0/version-1.1.0-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-1.1.0/version-1.1.0-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-1.1.0/version-1.1.0-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-1.1.1/version-1.1.1-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-1.1.1/version-1.1.1-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-1.1.1/version-1.1.1-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-1.1.1/version-1.1.1-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-1.1.1/version-1.1.1-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-1.1.1/version-1.1.1-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-1.1.1/version-1.1.1-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-1.1.1/version-1.1.1-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-1.1.1/version-1.1.1-performance\": {\n        \"title\": \"Performance\"\n      },\n      \"version-1.1.1/version-1.1.1-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-1.1.1/version-1.1.1-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-1.1.1/version-1.1.1-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-1.1.1/version-1.1.1-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-directives\": {\n        \"title\": \"Directives\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-performance\": {\n        \"title\": \"Performance\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-1.2.0-rc.1/version-1.2.0-rc.1-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-bootstrap\": {\n        \"title\": \"Bootstrapping\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-directives\": {\n        \"title\": \"Directives\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-enums\": {\n        \"title\": \"Enums\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-esm\": {\n        \"title\": \"ECMAScript Modules\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-faq\": {\n        \"title\": \"Frequently Asked Questions\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-getting-started\": {\n        \"title\": \"Getting started\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-introduction\": {\n        \"title\": \"Introduction\",\n        \"sidebar_label\": \"What & Why\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-nestjs\": {\n        \"title\": \"NestJS Integration\",\n        \"sidebar_label\": \"NestJS\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-performance\": {\n        \"title\": \"Performance\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-prisma\": {\n        \"title\": \"Prisma Integration\",\n        \"sidebar_label\": \"Prisma\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-scalars\": {\n        \"title\": \"Scalars\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-types-and-fields\": {\n        \"title\": \"Types and Fields\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-beta.3/version-2.0.0-beta.3-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-aws-lambda\": {\n        \"title\": \"AWS Lambda integration\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-directives\": {\n        \"title\": \"Directives\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-esm\": {\n        \"title\": \"ECMAScript Modules\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-migration-guide\": {\n        \"title\": \"Migration Guide\",\n        \"sidebar_label\": \"v1.x -> v2.0\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-beta.4/version-2.0.0-beta.4-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-beta.6/version-2.0.0-beta.6-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-migration-guide\": {\n        \"title\": \"Migration Guide\",\n        \"sidebar_label\": \"v1.x -> v2.0\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-rc.1/version-2.0.0-rc.1-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-azure-functions\": {\n        \"title\": \"Azure Functions Integration\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-browser-usage\": {\n        \"title\": \"Browser usage\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-rc.2/version-2.0.0-rc.2-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-emit-schema\": {\n        \"title\": \"Emitting the schema SDL\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-installation\": {\n        \"title\": \"Installation\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-rc.3/version-2.0.0-rc.3-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-authorization\": {\n        \"title\": \"Authorization\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-complexity\": {\n        \"title\": \"Query complexity\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-custom-decorators\": {\n        \"title\": \"Custom decorators\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-dependency-injection\": {\n        \"title\": \"Dependency injection\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-examples\": {\n        \"title\": \"Examples\",\n        \"sidebar_label\": \"List of examples\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-extensions\": {\n        \"title\": \"Extensions\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-generic-types\": {\n        \"title\": \"Generic Types\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-inheritance\": {\n        \"title\": \"Inheritance\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-interfaces\": {\n        \"title\": \"Interfaces\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-middlewares\": {\n        \"title\": \"Middleware and guards\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-resolvers\": {\n        \"title\": \"Resolvers\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-subscriptions\": {\n        \"title\": \"Subscriptions\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-unions\": {\n        \"title\": \"Unions\"\n      },\n      \"version-2.0.0-rc.4/version-2.0.0-rc.4-validation\": {\n        \"title\": \"Argument and Input validation\",\n        \"sidebar_label\": \"Validation\"\n      }\n    },\n    \"links\": {\n      \"Docs\": \"Docs\",\n      \"Examples\": \"Examples\",\n      \"FAQ\": \"FAQ\",\n      \"Donate\": \"Donate\",\n      \"GitHub\": \"GitHub\",\n      \"Blog\": \"Blog\"\n    },\n    \"categories\": {\n      \"Introduction\": \"Introduction\",\n      \"Beginner guides\": \"Beginner guides\",\n      \"Migration guide\": \"Migration guide\",\n      \"Advanced guides\": \"Advanced guides\",\n      \"Features\": \"Features\",\n      \"Integrations\": \"Integrations\",\n      \"Others\": \"Others\",\n      \"Recipes\": \"Recipes\",\n      \"Examples\": \"Examples\"\n    }\n  },\n  \"pages-strings\": {\n    \"Help Translate|recruit community translators for your project\": \"Help Translate\",\n    \"Edit this Doc|recruitment message asking to edit the doc source\": \"Edit\",\n    \"Translate this Doc|recruitment message asking to translate the docs\": \"Translate\"\n  }\n}\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"build\": \"npx docusaurus-build\",\n    \"prenew-release\": \"npm run --prefix ../ gen:docs -- --ref v$npm_config_release\",\n    \"new-release\": \"npx docusaurus-version $npm_config_release\",\n    \"postnew-release\": \"git restore ../docs\",\n    \"publish-gh-pages\": \"npx docusaurus-publish\",\n    \"rename-version\": \"npx docusaurus-rename-version\",\n    \"start\": \"npx docusaurus-start\"\n  },\n  \"devDependencies\": {\n    \"docusaurus\": \"^1.14.7\"\n  }\n}\n"
  },
  {
    "path": "website/pages/en/help.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require(\"react\");\n\nconst CompLibrary = require(\"../../core/CompLibrary.js\");\nconst Container = CompLibrary.Container;\nconst GridBlock = CompLibrary.GridBlock;\n\nconst siteConfig = require(process.cwd() + \"/siteConfig.js\");\n\nclass Help extends React.Component {\n  render() {\n    const supportLinks = [\n      {\n        content: \"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)\",\n        title: \"Browse Docs\",\n      },\n      {\n        content: \"Ask questions about the documentation and project\",\n        title: \"Join the community\",\n      },\n      {\n        content: \"Find out what's new with this project\",\n        title: \"Stay up to date\",\n      },\n    ];\n\n    return (\n      <div className=\"docMainWrapper wrapper\">\n        <Container className=\"mainContainer documentContainer postContainer\">\n          <div className=\"post\">\n            <header className=\"postHeader\">\n              <h2>Need help?</h2>\n            </header>\n            <p>This project is maintained by a dedicated group of people.</p>\n            <GridBlock contents={supportLinks} layout=\"threeColumn\" />\n          </div>\n        </Container>\n      </div>\n    );\n  }\n}\n\nmodule.exports = Help;\n"
  },
  {
    "path": "website/pages/en/index.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require(\"react\");\nconst fs = require(\"fs\");\n\nconst CompLibrary = require(\"../../core/CompLibrary.js\");\nconst MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */\nconst Container = CompLibrary.Container;\nconst GridBlock = CompLibrary.GridBlock;\n\nconst siteConfig = require(process.cwd() + \"/siteConfig.js\");\n\nfunction imgUrl(img) {\n  return siteConfig.baseUrl + \"img/\" + img;\n}\n\nfunction docUrl(doc, language) {\n  return siteConfig.baseUrl + \"docs/\" + (language ? language + \"/\" : \"\") + doc;\n}\n\nfunction pageUrl(page, language) {\n  return siteConfig.baseUrl + (language ? language + \"/\" : \"\") + page;\n}\n\nclass Button extends React.Component {\n  render() {\n    return (\n      <div className=\"pluginWrapper buttonWrapper\">\n        <a className=\"button\" href={this.props.href} target={this.props.target}>\n          {this.props.children}\n        </a>\n      </div>\n    );\n  }\n}\n\nButton.defaultProps = {\n  target: \"_self\",\n};\n\nconst SplashContainer = props => (\n  <div className=\"homeContainer\">\n    <div className=\"homeSplashFade\">\n      <div className=\"wrapper homeWrapper\">{props.children}</div>\n    </div>\n  </div>\n);\n\nconst Logo = props => (\n  <div className=\"project-logo\">\n    <img src={props.img_src} />\n  </div>\n);\n\nconst ProjectTitle = props => (\n  <h2 className=\"projectTitle\">\n    {siteConfig.title}\n    <small>{siteConfig.tagline}</small>\n  </h2>\n);\n\nconst PromoSection = props => (\n  <div className=\"section promoSection\">\n    <div className=\"promoRow\">\n      <div className=\"pluginRowBlock\">{props.children}</div>\n    </div>\n  </div>\n);\n\nclass HomeSplash extends React.Component {\n  render() {\n    let language = this.props.language || \"\";\n    return (\n      <SplashContainer>\n        <div className=\"inner\">\n          <Logo img_src={imgUrl(\"logo.png\")} />\n          <ProjectTitle />\n          <PromoSection>\n            <Button href={docUrl(\"introduction.html\", language)}>Introduction</Button>\n            <Button href={docUrl(\"getting-started.html\", language)}>Getting started</Button>\n            <Button href={docUrl(\"examples.html\", language)}>Examples</Button>\n          </PromoSection>\n        </div>\n      </SplashContainer>\n    );\n  }\n}\n\nconst Block = props => (\n  <Container\n    padding={[\"bottom\", \"top\"]}\n    id={props.id}\n    background={props.background}\n    className={props.className}\n  >\n    <GridBlock align={props.align || \"center\"} contents={props.children} layout={props.layout} />\n  </Container>\n);\n\nconst Features = props => (\n  <Block layout=\"fourColumn\" className=\"highlight features-section\">\n    {[\n      {\n        image: imgUrl(\"GraphQL_Logo.svg\"),\n        imageAlign: \"top\",\n        title: \"GraphQL\",\n        content:\n          \"Define your whole schema, including types, interfaces, enums, unions and subscriptions\",\n      },\n      {\n        image: imgUrl(\"ts-logo.png\"),\n        imageAlign: \"top\",\n        title: \"TypeScript\",\n        content:\n          \"Create the schema, types and resolvers only with TypeScript, using classes and decorators! \",\n      },\n      {\n        image: imgUrl(\"tools.svg\"),\n        imageAlign: \"top\",\n        title: \"Advanced features\",\n        content:\n          \"Use features like automatic validation, authorization guards, dependency injection and plenty more...\",\n      },\n    ]}\n  </Block>\n);\n\nconst objectTypeSnippet = fs\n  .readFileSync(process.cwd() + \"/pages/snippets/object-type.md\")\n  .toString();\nconst DefineSchemaSection = props => (\n  <Container\n    id=\"define-schema\"\n    padding={[\"bottom\", \"top\"]}\n    background=\"light\"\n    className=\"snippet-container highlight\"\n  >\n    <GridBlock\n      align=\"left\"\n      contents={[\n        {\n          title: \"Define schema\",\n          content:\n            \"Use only classes and decorators to define your GraphQL schema. No need to define types in SDL and no need to create interfaces for them!<br><br>This way you will have only one source of truth, so say goodbye to all field type mismatches, typos and annoying refactoring.\",\n        },\n      ]}\n    />\n    <div className=\"snippet\">\n      <MarkdownBlock>{objectTypeSnippet}</MarkdownBlock>\n    </div>\n  </Container>\n);\n\nconst testabilitySnippet = fs\n  .readFileSync(process.cwd() + \"/pages/snippets/testability.md\")\n  .toString();\nconst ResolversSection = props => (\n  <Container id=\"validation\" padding={[\"bottom\", \"top\"]} className=\"snippet-container\">\n    <div className=\"snippet\">\n      <MarkdownBlock>{testabilitySnippet}</MarkdownBlock>\n    </div>\n    <GridBlock\n      align=\"left\"\n      contents={[\n        {\n          title: \"Create resolvers\",\n          content:\n            \"Implement queries and mutations as normal class methods! Dependency injection support and decorators abstraction provides great separation of business logic from the underlying transport layer.<br><br>That gives you really easy testability, so you can just provide mocks of dependencies to prevent side effects and unit test your resolvers like a simple services which methods only take some parameters and return results.\",\n        },\n      ]}\n    />\n  </Container>\n);\n\nconst validationSnippet = fs\n  .readFileSync(process.cwd() + \"/pages/snippets/validation.md\")\n  .toString();\nconst Validation = props => (\n  <Container\n    id=\"validation\"\n    padding={[\"bottom\", \"top\"]}\n    className=\"snippet-container highlight\"\n    background=\"light\"\n  >\n    <GridBlock\n      align=\"left\"\n      contents={[\n        {\n          title: \"Easy validation\",\n          content:\n            \"Forget about manual inputs and arguments validation! No need to create custom scalars to limit the length of a string or the range of an int.<br><br>Just use decorators from <a href='https://github.com/typestack/class-validator' target='_blank'>class-validator</a> library and declare the requirements of the inputs. It couldn't be easier!\",\n        },\n      ]}\n    />\n    <div className=\"snippet\">\n      <MarkdownBlock>{validationSnippet}</MarkdownBlock>\n    </div>\n  </Container>\n);\n\nconst typeormSnippet = fs.readFileSync(process.cwd() + \"/pages/snippets/typeorm.md\").toString();\nconst InteroperableSection = props => (\n  <Container id=\"interoperable\" padding={[\"bottom\", \"top\"]} className=\"snippet-container\">\n    <div className=\"snippet\">\n      <MarkdownBlock>{typeormSnippet}</MarkdownBlock>\n    </div>\n    <GridBlock\n      align=\"left\"\n      contents={[\n        {\n          title: \"Interoperable\",\n          content:\n            \"Although TypeGraphQL is data-layer library agnostic, it integrates well with other decorator-based libraries, like [TypeORM](https://github.com/typeorm/typeorm), [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) or [Typegoose](https://github.com/typegoose/typegoose).<br><br>This allows you to define both the GraphQL type and the entity in a single class - no need to jump between multiple files to add or rename some properties.\",\n        },\n      ]}\n    />\n  </Container>\n);\n\nconst CollectiveSection = props => (\n  <React.Fragment>\n    <Container id=\"collective\" padding={[\"top\"]} className=\"snippet-container highlight\">\n      <GridBlock\n        align=\"left\"\n        contents={[\n          {\n            title: \"Community supported\",\n            content:\n              \"TypeGraphQL is an MIT-licensed open source project. It doesn't have a large company that sits behind - its ongoing development is possible only thanks to the support by the community.<br><br>If you fell in love with TypeGraphQL, please consider supporting our efforts and help it grow, especially if you are using it commercially - just to ensure that the project which your product relies on is actively maintained and improved.\",\n          },\n        ]}\n      />\n      <div className=\"collective-button\">\n        <a href=\"https://opencollective.com/typegraphql\">\n          <img\n            srcSet=\"https://opencollective.com/typegraphql/donate/button.png?color=blue, https://opencollective.com/typegraphql/donate/button@2x.png?color=blue 2x\"\n            src=\"https://opencollective.com/typegraphql/donate/button.png?color=blue\"\n          />\n        </a>\n      </div>\n    </Container>\n    <div id=\"sponsors\" className=\"snippet-container\">\n      <div className=\"wrapper\">\n        <h3 className=\"title\">Gold Sponsors 🏆</h3>\n        <blockquote className=\"note\">\n          <span>Please ask your company to support this open source project by</span>{\" \"}\n          <a href=\"https://opencollective.com/typegraphql/contribute/gold-sponsors-8340\">\n            becoming a gold sponsor\n          </a>{\" \"}\n          <span>and getting a premium technical support from our core contributors.</span>\n        </blockquote>\n        <h3 className=\"title\">Silver Sponsors 🥈</h3>\n        <div className=\"tiles\">\n          <a href=\"https://leofame.com/buy-instagram-followers\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"leofame.png\")} style={{ width: 250 }} />\n            <span>Leofame</span>\n          </a>\n        </div>\n        <h3 className=\"title\">Bronze Sponsors 🥉</h3>\n        <div className=\"tiles\">\n          <a href=\"https://www.ligrsystems.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"live-graphics-system.png\")} style={{ width: 55 }} />\n            <span>Live Graphic Systems</span>\n          </a>\n          <a href=\"https://github.com/joinlifex\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"felix.png\")} style={{ width: 60 }} />\n            <span>Felix Technologies</span>\n          </a>\n          <a href=\"https://instinctools.com/manufacturing/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"instinctools.svg\")} style={{ width: 100 }} />\n            <span>*instinctools</span>\n          </a>\n        </div>\n        <div className=\"tiles\">\n          <a href=\"https://guidebook.betwinner.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"betwinner.svg\")} style={{ width: 100 }} />\n            <span>BetWinner</span>\n          </a>\n          <a href=\"https://buzzvoice.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"logo-buzzv.png\")} style={{ width: 70 }} />\n            <span>BuzzVoice</span>\n          </a>\n          <a href=\"https://www.socialwick.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"socialwick-logo.png\")} style={{ width: 50 }} />\n            <span>SocialWick</span>\n          </a>\n          <a href=\"https://www.c19.cl/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"c19.png\")} style={{ width: 40 }} />\n            <span>C19</span>\n          </a>\n          <a href=\"https://novecasino.net/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"nove_casino.svg\")} style={{ width: 70 }} />\n            <span>Nove Casino</span>\n          </a>\n          <a\n            href=\"https://play-fortune.pl/gry-online/jednoreki-bandyta/\"\n            target=\"_blank\"\n            rel=\"sponsored\"\n          >\n            <img src={imgUrl(\"play_fortune.png\")} style={{ width: 80 }} />\n            <span>Play Fortune</span>\n          </a>\n          <a href=\"https://wechoosethemoon.org/kasyna-online/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"moonkasyno.png\")} style={{ width: 60 }} />\n            <span>MoonKasyno</span>\n          </a>\n          <a href=\"https://www.casinobillions.com/pl/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"kasyno-online.png\")} style={{ width: 50 }} />\n            <span>Kasyno Online</span>\n          </a>\n          <a href=\"https://www.fbpostlikes.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"fbpostlikes.webp\")} style={{ width: 90 }} />\n            <span>FBPostLikes</span>\n          </a>\n        </div>\n        <div className=\"tiles\">\n          <a href=\"https://sidesmedia.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"sidesmedia.png\")} style={{ width: 40 }} />\n            <span>SidesMedia</span>\n          </a>\n          <a\n            href=\"https://www.socialfollowers.uk/buy-tiktok-followers/\"\n            target=\"_blank\"\n            rel=\"sponsored\"\n          >\n            <img src={imgUrl(\"social_followers.png\")} style={{ width: 60 }} />\n            <span>Social Followers</span>\n          </a>\n          <a href=\"https://igcomment.com/buy-instagram-comments/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"ig-comment.png\")} style={{ width: 80 }} />\n            <span>IG Comment</span>\n          </a>\n          <a href=\"https://twicsy.com/buy-instagram-followers\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"twicsy.svg\")} style={{ width: 100 }} />\n            <span>Twicsy</span>\n          </a>\n          <a href=\"https://buzzoid.com/buy-instagram-followers/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"buzzoid.svg\")} style={{ width: 90 }} />\n            <span>Buzzoid</span>\n          </a>\n          <a href=\"https://views4you.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"v4u.png\")} style={{ width: 80 }} />\n            <span>Views4You</span>\n          </a>\n          <a\n            href=\"https://au.trustpilot.com/review/bestpayidpokies.net\"\n            target=\"_blank\"\n            rel=\"sponsored\"\n          >\n            <img src={imgUrl(\"payid_pookies.avif\")} style={{ width: 50 }} />\n            <span>PayID Pokies</span>\n          </a>\n          <a href=\"https://global.fun88.com/\" target=\"_blank\" rel=\"sponsored\">\n            <img src={imgUrl(\"fun88.png\")} style={{ width: 40 }} />\n            <span>Fun88</span>\n          </a>\n        </div>\n        <h3 className=\"title\">Members 💪</h3>\n        <a href=\"https://opencollective.com/typegraphql#contributors\">\n          <img src=\"https://opencollective.com/typegraphql/tiers/members.svg?avatarHeight=45&width=320&button=false\" />\n        </a>\n        <h3 className=\"title\">GitHub Sponsors 🐙</h3>\n        <a href=\"https://github.com/sponsors/TypeGraphQL\">\n          <img src={imgUrl(\"github-sponsors.svg\")} />\n        </a>\n      </div>\n    </div>\n  </React.Fragment>\n);\n\nconst WantMoreSection = props => {\n  let language = props.language || \"\";\n  return (\n    <div className=\"want-more-section\">\n      <div className=\"productShowcaseSection\" style={{ textAlign: \"center\" }}>\n        <h2>Want more?</h2>\n        That was only a tip of the iceberg. Interested?\n        <br />\n        Give it a try and experiment with TypeGraphQL! It will reduce your codebase size by a half\n        or more!\n        <br />\n      </div>\n      <div className=\"want-more-buttons\">\n        <Button href={docUrl(\"getting-started.html\", language)}>Getting started</Button>\n        <Button href={docUrl(\"examples.html\", language)}>Examples</Button>\n      </div>\n    </div>\n  );\n};\n\n// const Showcase = props => {\n//   if ((siteConfig.users || []).length === 0) {\n//     return null;\n//   }\n//   const showcase = siteConfig.users\n//     .filter(user => {\n//       return user.pinned;\n//     })\n//     .map((user, i) => {\n//       return (\n//         <a href={user.infoLink} key={i}>\n//           <img src={user.image} title={user.caption} />\n//         </a>\n//       );\n//     });\n\n//   return (\n//     <div className=\"productShowcaseSection paddingBottom\">\n//       <h2>{\"Who's Using This?\"}</h2>\n//       <p>This project is used by all these people</p>\n//       <div className=\"logos\">{showcase}</div>\n//       <div className=\"more-users\">\n//         <a className=\"button\" href={pageUrl(\"users.html\", props.language)}>\n//           More {siteConfig.title} Users\n//         </a>\n//       </div>\n//     </div>\n//   );\n// };\n\nclass Index extends React.Component {\n  render() {\n    let language = this.props.language || \"\";\n\n    return (\n      <div>\n        <HomeSplash language={language} />\n        <div className=\"mainContainer\">\n          <Features />\n          <DefineSchemaSection />\n          <ResolversSection />\n          <Validation />\n          <InteroperableSection />\n          <CollectiveSection />\n          <WantMoreSection language={language} />\n          {/* <Showcase language={language} /> */}\n        </div>\n      </div>\n    );\n  }\n}\n\nmodule.exports = Index;\n"
  },
  {
    "path": "website/pages/en/users.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require(\"react\");\n\nconst CompLibrary = require(\"../../core/CompLibrary.js\");\nconst Container = CompLibrary.Container;\n\nconst siteConfig = require(process.cwd() + \"/siteConfig.js\");\n\nclass Users extends React.Component {\n  render() {\n    if ((siteConfig.users || []).length === 0) {\n      return null;\n    }\n    const showcase = siteConfig.users.map((user, i) => {\n      return (\n        <a href={user.infoLink} key={i}>\n          <img src={user.image} title={user.caption} />\n        </a>\n      );\n    });\n\n    return (\n      <div className=\"mainContainer\">\n        <Container padding={[\"bottom\", \"top\"]}>\n          <div className=\"showcaseSection\">\n            <div className=\"prose\">\n              <h1>Who's Using This?</h1>\n              <p>This project is used by many folks</p>\n            </div>\n            <div className=\"logos\">{showcase}</div>\n            <p>Are you using this project?</p>\n            <a\n              href=\"https://github.com/facebook/docusaurus/edit/master/website/siteConfig.js\"\n              className=\"button\"\n            >\n              Add your company\n            </a>\n          </div>\n        </Container>\n      </div>\n    );\n  }\n}\n\nmodule.exports = Users;\n"
  },
  {
    "path": "website/pages/en/versions.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require(\"react\");\n\nconst CompLibrary = require(\"../../core/CompLibrary\");\n\nconst Container = CompLibrary.Container;\n\nconst CWD = process.cwd();\n\nconst versions = require(`${CWD}/versions.json`);\n\nfunction Versions(props) {\n  const { config: siteConfig } = props;\n  const latestVersion = versions[0];\n  const repoUrl = `https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`;\n  const defaultDocPage = \"getting-started.html\";\n\n  return (\n    <div className=\"docMainWrapper wrapper\">\n      <Container className=\"mainContainer versionsContainer\">\n        <div className=\"post\">\n          <header className=\"postHeader\">\n            <h1>{siteConfig.title} Versions</h1>\n          </header>\n          <h3 id=\"latest\">Current version (Stable)</h3>\n          <table className=\"versions\">\n            <tbody>\n              <tr>\n                <th>{latestVersion}</th>\n                <td>\n                  <a href={`${siteConfig.baseUrl}${siteConfig.docsUrl}/${defaultDocPage}`}>\n                    Documentation\n                  </a>\n                </td>\n                <td>\n                  <a href={`${repoUrl}/releases/tag/v${latestVersion}`}>Release Notes</a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <p>\n            This is the version that is configured automatically when you first install this\n            project.\n          </p>\n          <h3 id=\"rc\">Pre-release versions</h3>\n          <table className=\"versions\">\n            <tbody>\n              <tr>\n                <th>master</th>\n                <td>\n                  <a href={`${siteConfig.baseUrl}${siteConfig.docsUrl}/next/${defaultDocPage}`}>\n                    Documentation\n                  </a>\n                </td>\n                <td>\n                  <a href={repoUrl}>Source Code</a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <p>Other text describing this section.</p>\n          <h3 id=\"archive\">Past Versions</h3>\n          <table className=\"versions\">\n            <tbody>\n              {versions.map(\n                version =>\n                  version !== latestVersion && (\n                    <tr key={version}>\n                      <th>{version}</th>\n                      <td>\n                        <a\n                          href={`${siteConfig.baseUrl}${siteConfig.docsUrl}/${version}/${defaultDocPage}`}\n                        >\n                          Documentation\n                        </a>\n                      </td>\n                      <td>\n                        <a href={`${repoUrl}/releases/tag/v${version}`}>Release Notes</a>\n                      </td>\n                    </tr>\n                  ),\n              )}\n            </tbody>\n          </table>\n          <p>\n            You can find past versions of this project on <a href={`${repoUrl}/releases`}>GitHub</a>\n            .\n          </p>\n        </div>\n      </Container>\n    </div>\n  );\n}\n\nmodule.exports = Versions;\n"
  },
  {
    "path": "website/pages/snippets/object-type.md",
    "content": "<!-- markdownlint-disable MD041 -->\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  get averageRating() {\n    const sum = this.ratings.reduce((a, b) => a + b, 0);\n    return sum / this.ratings.length;\n  }\n}\n```\n"
  },
  {
    "path": "website/pages/snippets/testability.md",
    "content": "<!-- markdownlint-disable MD041 -->\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    private readonly recipeRepository: Repository<Recipe>,\n    private readonly rateRepository: Repository<Rate>,\n  ) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    return this.recipeRepository.findOneById(recipeId);\n  }\n\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"recipe\") recipeInput: RecipeInput) {\n    const newRecipe = this.recipeRepository.create(recipeInput);\n    return this.recipeRepository.save(newRecipe);\n  }\n\n  @FieldResolver()\n  ratings(@Root() recipe: Recipe) {\n    return this.rateRepository.find({ recipeId: recipe.id });\n  }\n}\n```\n"
  },
  {
    "path": "website/pages/snippets/typeorm.md",
    "content": "<!-- markdownlint-disable MD041 -->\n\n```ts\n@Entity()\n@ObjectType()\nexport class Rate {\n  @PrimaryGeneratedColumn()\n  readonly id: number;\n\n  @Field(type => Int)\n  @Column({ type: \"int\" })\n  value: number;\n\n  @Field(type => User)\n  @ManyToOne(type => User)\n  user: Promise<User>;\n\n  @Field()\n  @CreateDateColumn()\n  date: Date;\n\n  @ManyToOne(type => Recipe)\n  recipe: Promise<Recipe>;\n}\n```\n"
  },
  {
    "path": "website/pages/snippets/validation.md",
    "content": "<!-- markdownlint-disable MD041 -->\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @MaxArraySize(25)\n  ingredients: string[];\n}\n```\n"
  },
  {
    "path": "website/sidebars.json",
    "content": "{\n  \"docs\": {\n    \"Introduction\": [\"introduction\"],\n    \"Beginner guides\": [\n      \"installation\",\n      \"getting-started\",\n      \"types-and-fields\",\n      \"resolvers\",\n      \"bootstrap\",\n      \"esm\"\n    ],\n    \"Migration guide\": [\"migration-guide\"],\n    \"Advanced guides\": [\n      \"scalars\",\n      \"enums\",\n      \"unions\",\n      \"interfaces\",\n      \"subscriptions\",\n      \"directives\",\n      \"extensions\"\n    ],\n    \"Features\": [\n      \"dependency-injection\",\n      \"authorization\",\n      \"validation\",\n      \"inheritance\",\n      \"generic-types\",\n      \"middlewares\",\n      \"custom-decorators\",\n      \"complexity\"\n    ],\n    \"Integrations\": [\"prisma\", \"nestjs\"],\n    \"Others\": [\"emit-schema\", \"performance\"],\n    \"Recipes\": [\"browser-usage\", \"aws-lambda\", \"azure-functions\"]\n  },\n  \"examples\": {\n    \"Examples\": [\"examples\"]\n  },\n  \"others\": {\n    \"Others\": [\"faq\"]\n  }\n}\n"
  },
  {
    "path": "website/siteConfig.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/* List of projects/orgs using your project for the users page */\nconst users = [\n  // {\n  //   caption: \"User1\",\n  //   image: \"/type-graphql/img/docusaurus.svg\",\n  //   infoLink: \"https://www.facebook.com\",\n  //   pinned: true,\n  // },\n];\n\nconst siteConfig = {\n  title: \"TypeGraphQL\" /* title for your website */,\n  tagline: \"Modern framework for GraphQL API in Node.js\",\n  url: \"https://typegraphql.com\" /* your website url */,\n  baseUrl: \"/\" /* base url for your project */,\n  cname: \"typegraphql.com\" /* the CNAME for your website */,\n  projectName: \"type-graphql\",\n  headerLinks: [\n    { doc: \"introduction\", label: \"Docs\" },\n    // { doc: \"doc4\", label: \"API\" },\n    { doc: \"examples\", label: \"Examples\" },\n    { doc: \"faq\", label: \"FAQ\" },\n    { href: \"https://opencollective.com/typegraphql\", label: \"Donate\" },\n    { href: \"https://github.com/MichalLytek/type-graphql\", label: \"GitHub\" },\n    { blog: true, label: \"Blog\" },\n    { search: true },\n  ],\n  algolia: {\n    apiKey: \"2cf66434100c0e30ca9ff499830e7b77\",\n    indexName: \"typegraphql\",\n  },\n  users,\n  /* path to images for header/footer */\n  headerIcon: \"img/logo.png\",\n  footerIcon: \"img/logo.png\",\n  favicon: \"img/favicon.png\",\n  editUrl: \"https://github.com/MichalLytek/type-graphql/edit/master/docs/\",\n  /* colors for website */\n  colors: {\n    primaryColor: \"#222\",\n    secondaryColor: \"#333\",\n  },\n  /* custom fonts for website */\n  /*fonts: {\n    myFont: [\n      \"Times New Roman\",\n      \"Serif\"\n    ],\n    myOtherFont: [\n      \"-apple-system\",\n      \"system-ui\"\n    ]\n  },*/\n  // This copyright info is used in /core/Footer.js and blog rss/atom feeds.\n  copyright: \"Copyright © \" + new Date().getFullYear() + \" Michał Lytek\",\n  organizationName: \"MichalLytek\", // or set an env variable ORGANIZATION_NAME\n  projectName: \"type-graphql\", // or set an env variable PROJECT_NAME\n  usePrism: true,\n  scripts: [\"https://buttons.github.io/buttons.js\"],\n  // You may provide arbitrary config keys to be used as needed by your template.\n  repoUrl: \"https://github.com/MichalLytek/type-graphql\",\n  /* On page navigation for the current documentation page */\n  onPageNav: \"separate\",\n  gaTrackingId: \"UA-117093147-1\",\n};\n\nmodule.exports = siteConfig;\n"
  },
  {
    "path": "website/static/css/custom.css",
    "content": "/* your custom css */\n\n@import \"./prism-theme.css\";\n\n* {\n  box-sizing: border-box;\n}\n\nhtml {\n  --color-main-dark: white;\n  --color-main-light: #18191a;\n  --color-link: #2f7bc5;\n  --color-secondary-background: #f9f9f9;\n  --color-secondary-text: #717171;\n  --color-code-block: rgba(27, 31, 35, 0.05);\n  --color-blockquote-text: #6a737d;\n  --color-other-background: #f2f2f2;\n}\n\nhtml.theme-mode--light {\n  --color-main-dark: white;\n  --color-main-light: #18191a;\n  --color-link: #2f7bc5;\n  --color-secondary-background: #f9f9f9;\n  --color-secondary-text: #717171;\n  --color-code-block: rgba(27, 31, 35, 0.05);\n  --color-blockquote-text: #6a737d;\n  --color-other-background: #f2f2f2;\n}\n\nhtml.theme-mode--dark {\n  --color-main-dark: #18191a;\n  --color-main-light: #f1f1f1;\n  --color-link: #6daff0;\n  --color-secondary-background: #111111;\n  --color-secondary-text: #a3a3a3;\n  --color-code-block: rgba(255, 255, 255, 0.07);\n  --color-blockquote-text: #f1f1f1;\n  --color-other-background: #151515;\n}\n\nbody {\n  background: var(--color-main-dark);\n  color: var(--color-main-light);\n}\n\nblockquote {\n  color: var(--color-blockquote-text);\n}\n\n#theme-mode-btn {\n  position: fixed;\n  top: 50px;\n  left: 0;\n  cursor: pointer;\n  padding: 2px 5px;\n  z-index: 11001;\n}\n\n@media (max-width: 1023px) {\n  #theme-mode-btn {\n    top: 100px;\n    left: unset;\n    right: 36px;\n  }\n}\n\n.theme-mode-btn--dark {\n  color: black;\n  background-color: lightgrey;\n}\n\n.theme-mode-btn--light {\n  color: white;\n  background-color: grey;\n}\n\n.productShowcaseSection h2 {\n  color: var(--color-main-light);\n}\n\n.toc {\n  color: var(--color-main-light);\n}\n\n.toc .toggleNav .navGroup .navGroupCategoryTitle {\n  color: var(--color-main-light);\n}\n\n.toc .toggleNav ul li a {\n  color: var(--color-secondary-text);\n}\n\n.toc .toggleNav ul li.navListItemActive a {\n  color: var(--color-main-light);\n}\n\n.onPageNav .toc-headings > li > a.active,\n.onPageNav .toc-headings > li > a.hover {\n  color: var(--color-main-light);\n}\n\n.toc .toggleNav ul li a:hover,\n.toc .toggleNav ul li a:focus {\n  color: var(--color-main-light);\n}\ntable tr:nth-child(2n) {\n  background-color: var(--color-secondary-background);\n}\n.onPageNav a {\n  color: var(--color-secondary-text);\n}\n\na,\na:hover {\n  color: var(--color-link);\n  text-decoration: none;\n}\n\n.mainContainer {\n  padding-bottom: 0;\n}\n\n.lightBackground {\n  background: var(--color-secondary-background);\n}\n\n.container.highlight {\n  background-color: var(--color-secondary-background);\n}\n\n.snippet-container > .wrapper {\n  display: flex;\n  align-items: center;\n}\n\n.snippet-container > .wrapper > .gridBlock {\n  margin: -50px 25px 25px 25px;\n}\n\n.snippet {\n  flex-grow: 1;\n  max-width: 450px;\n}\n\n.snippet code {\n  padding: 15px 30px 15px 15px;\n}\n\n#sponsors {\n  background-color: var(--color-secondary-background);\n  margin-top: -36px;\n  padding-bottom: 60px;\n}\n\n#sponsors h3.title {\n  margin-bottom: 1.5em;\n}\n\n#sponsors blockquote.note {\n  background-color: var(--color-secondary-background);\n  border-left: 8px solid #f1f1f1;\n  padding: 15px 30px 15px 15px;\n}\n\n#sponsors .wrapper {\n  display: block;\n  padding-left: 45px;\n  padding-right: 45px;\n}\n\n#sponsors .tiles {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n}\n#sponsors .tiles > a {\n  display: flex;\n  flex-direction: column;\n  text-align: center;\n  padding: 0 20px 20px;\n  align-items: center;\n  justify-content: stretch;\n}\n#sponsors .tiles > a > :first-child {\n  flex-grow: 1;\n  margin-bottom: 10px;\n}\n#sponsors .tiles > a > img {\n  object-fit: contain;\n}\n\n.want-more-section {\n  padding: 30px 0;\n}\n\n.want-more-section,\n.container.features-section {\n  background-color: var(--color-other-background);\n}\n\n.want-more-buttons {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  margin: 30px 0 20px;\n}\n\n.collective-button {\n  width: 298px;\n  flex-shrink: 0;\n}\n\n.button {\n  margin: 4px;\n  color: #c04392;\n  border-color: #c04392;\n}\n\n.button:hover {\n  background-color: #c04392;\n}\n\n.projectTitle {\n  font-weight: 600;\n  color: var(--color-link);\n}\n\n.projectTitle > small {\n  font-weight: 300;\n}\n\n.project-logo img {\n  max-width: 230px;\n  padding-bottom: 20px;\n  box-sizing: border-box;\n}\n\n.nav-footer {\n  background-color: #222;\n}\n\n@media only screen and (min-device-width: 360px) and (max-device-width: 736px) {\n  .snippet-container > .wrapper {\n    flex-direction: column;\n  }\n  .snippet-container > .wrapper > .gridBlock {\n    padding: 20px 0;\n    margin: 0;\n  }\n  .snippet {\n    max-width: 100%;\n    order: 2;\n    width: 100%;\n  }\n  .project-logo img {\n    max-width: 150px;\n  }\n  .nav.toc {\n    width: 100%;\n  }\n  #sponsors .wrapper {\n    padding: 40px 20px 0;\n  }\n}\n\n@media only screen and (min-width: 1024px) {\n  .snippet-container > .wrapper {\n    flex-direction: row;\n  }\n  .snippet {\n    max-width: 100%;\n  }\n}\n\n@media (max-width: 480px) {\n  .projectTitle {\n    margin-top: 1em;\n  }\n  .project-logo img {\n    padding-bottom: 0;\n  }\n}\n\n@media only screen and (max-width: 1023px) {\n}\n\n@media only screen and (min-width: 1400px) {\n}\n\n@media only screen and (min-width: 1500px) {\n}\n\n/* Dark mode button */\n\n.toggle {\n  display: -webkit-box;\n  display: flex;\n  -webkit-box-align: center;\n  align-items: center;\n  justify-content: space-around;\n  max-width: 140px;\n}\n.toggle span {\n  margin: 0 0.25rem;\n}\n.toggle input[type=\"checkbox\"] {\n  height: 0;\n  width: 0;\n  visibility: hidden;\n  margin: 0;\n}\n.toggle input[type=\"checkbox\"]:checked + label {\n  background: #c04392;\n}\n.toggle input[type=\"checkbox\"]:checked + label:after {\n  left: calc(100% - 2px);\n  -webkit-transform: translateX(-100%);\n  transform: translateX(-100%);\n}\n.toggle label {\n  cursor: pointer;\n  width: 50px;\n  height: 20px;\n  background: #7f2f61;\n  display: block;\n  border-radius: 40px;\n  position: relative;\n}\n.toggle label:after {\n  content: \"\";\n  position: absolute;\n  top: 2px;\n  left: 2px;\n  width: 16px;\n  height: 16px;\n  background: #fff;\n  border-radius: 40px;\n  -webkit-transition: 0.3s;\n  transition: 0.3s;\n}\n\n.screen-reader-text {\n  border: 0;\n  clip: rect(1px, 1px, 1px, 1px);\n  -webkit-clip-path: inset(50%);\n  clip-path: inset(50%);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute !important;\n  width: 1px;\n  word-wrap: normal !important;\n}\n\n.center-list-item {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n"
  },
  {
    "path": "website/static/css/prism-theme.css",
    "content": "code {\n  background: var(--color-code-block);\n}\n\n.token.function {\n  color: #dcdcaa;\n}\n\n.token.punctuation,\n.token.operator,\n.token.constant,\n.hljs.graphql {\n  color: #d4d4d4;\n}\n\n.token.keyword,\n.token.boolean {\n  color: #569cd6;\n}\n\n.token.class-name,\n.token.builtin {\n  color: #4ec9b0;\n}\n\n.token.number {\n  color: #b5cea8;\n}\n\n.token.comment {\n  color: #6a9955;\n}\n\n.token.string {\n  color: #ce9178;\n}\n\n.token.regex {\n  color: #d16969;\n}\n\n.hljs,\n.token.attr-name,\n.token.property {\n  color: #9cdcfe;\n}\n\n.hljs.graphql .token.attr-name {\n  color: #9cdcfe;\n}\n\n.hljs a {\n  color: inherit !important;\n}\n\n.hljs {\n  background: rgb(30, 30, 30);\n}\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-0.16.0-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict access to some actions or reading some data only for specific group of users.\n\nIn express.js (and other Node.js framework) we use middlewares for this, like `passport.js` or the custom ones. However in GraphQL's resolvers architecture we don't have middlewares so we have to imperatively call the auth checking function and manually passing context data in each resolver, which might be quite tedious work.\n\nAnd that's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use?\n\nAt first, you need to use `@Authorized` decorator as a guard on a field or a query/mutation.\nExample object type's fields guards:\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nYou can leave the `@Authorized` decorator brackets empty or you can specify the roles that the user needs to have to get access to the field, query or mutation.\nBy default the roles are `string` but you can change it easily as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThis 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.\n\nSample query and mutations guards:\n\n```typescript\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data only for logged users\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Only for authed users!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop database ;)\";\n  }\n}\n```\n\nAuthed 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`.\n\nIn next step, you need to create your auth checker function. Its implementation may depends on your business logic:\n\n```typescript\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // here you can read user from context\n  // and check his permission in db against `roles` argument\n  // that comes from `@Authorized`, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or false if access denied\n};\n```\n\nThe second argument of `AuthChecker` generic type is `RoleType` - use it together with `@Authorized` decorator generic type.\n\nThe last step is to register the function while building the schema:\n\n```typescript\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // here we register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing authorization error.\n\n## Recipes\n\nYou can also use `TypeGraphQL` with JWT authentication. Example using `apollo-server-express`:\n\n```typescript\nimport express from \"express\";\nimport { ApolloServer, gql } from \"apollo-server-express\";\nimport * as jwt from \"express-jwt\";\n\nimport { schema } from \"../example/above\";\n\nconst app = express();\nconst path = \"/graphql\";\n\n// Create a GraphQL server\nconst server = new ApolloServer({\n  schema,\n  context: ({ req }) => {\n    const context = {\n      req,\n      user: req.user, // `req.user` comes from `express-jwt`\n    };\n    return context;\n  },\n});\n\n// Mount a jwt or other authentication middleware that is run before the GraphQL execution\napp.use(\n  path,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply the GraphQL server middleware\nserver.applyMiddleware({ app, path });\n\n// Launch the express server\napp.listen({ port: 4000 }, () =>\n  console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`),\n);\n```\n\nThen you can use standard, token based authorization in HTTP header like in classic REST API and take advantages of `TypeGraphQL` authorization mechanism.\n\n## Example\n\nYou can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-0.16.0-bootstrap\noriginal_id: bootstrap\n---\n\nAfter creating our resolvers, types 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 by HTTP server, WebSockets or even MQTT.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, you need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object you must provide a `resolvers` property, which can be an array of resolver classes:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SampleResolver],\n});\n```\n\nHowever, when there are several dozen of resolver classes, manual imports can be tedious.\nSo you can also provide an array of paths to resolver module files instead, which can include globs:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/modules/**/*.resolver.ts\", __dirname + \"/resolvers/**/*.ts\"],\n});\n```\n\nThere are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  });\n\n  // other initialization code, like creating http server\n}\n\nbootstrap(); // actually run the async function\n```\n\n## Create HTTP GraphQL endpoint\n\nIn 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):\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Building schema here\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    playground: true,\n  });\n\n  // Start the server\n  const { url } = await server.listen(4000);\n  console.log(`Server is running, GraphQL Playground available at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install `apollo-server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-0.16.0-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in client app\n\nSometimes 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.\n\nAs 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:\n\n```js\nplugins: [\n    ..., // here any other existing plugins that you already have\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, function (result) {\n        result.request = result.request.replace(/type-graphql/, \"type-graphql/browser-shim\");\n    }),\n]\n```\n\nAlso, thanks to this your bundle will be much lighter as you don't embedded the whole TypeGraphQL library code in your app.\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-0.16.0-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThe 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` .\n\nAll 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.\n\n## How to use?\n\nAt first, you need to pass `complexity` as an option to the decorator on a field/query/mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nYou can omit the `complexity` option if the complexity value is 1.\nYou 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.\n\nIn next step, you need to integrate `graphql-query-complexity` with your GraphQL server.\n\n```typescript\n// Create GraphQL server\nconst server = new GraphQLServer({ schema });\n\n// Configure server options\nconst serverOptions: Options = {\n  port: 4000,\n  endpoint: \"/graphql\",\n  playground: \"/playground\",\n  validationRules: req => [\n    queryComplexity({\n      // The maximum allowed query complexity, queries above this threshold will be rejected\n      maximumComplexity: 8,\n      // The query variables. This is needed because the variables are not available\n      // in the visitor of the graphql-js library\n      variables: req.query.variables,\n      // Optional callback function to retrieve the determined query complexity\n      // Will be invoked weather the query is rejected or not\n      // This can be used for logging or to implement rate limiting\n      onComplete: (complexity: number) => {\n        console.log(\"Query Complexity:\", complexity);\n      },\n      estimators: [\n        // Using fieldConfigEstimator is mandatory to make it work with type-graphql\n        fieldConfigEstimator(),\n        // This will assign each field a complexity of 1 if no other estimator\n        // returned a value. We can define the default value for field not explicitly annotated\n        simpleEstimator({\n          defaultComplexity: 1,\n        }),\n      ],\n    }),\n  ],\n};\n\n// Start the server\nserver.start(serverOptions, ({ port, playground }) => {\n  console.log(\n    `Server is running, GraphQL Playground available at http://localhost:${port}${playground}`,\n  );\n});\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit[graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-0.16.0-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is to register 3rd party container. Example using TypeDI:\n\n```typescript\nimport { useContainer, buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// register the 3rd party IOC container\nuseContainer(Container);\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n});\n```\n\nThen, your resolvers will be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nAnd the sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n### Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/using-container).\n\n## Scoped containers\n\nDependency injection is a really powerful pattern. But some advanced users may encounter the need of 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.\n\nTo register scoped container, you need to make some changes in the server bootstrapping config code.\nAt first you need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return instance of the container scoped to the request.\n\nFor simple container libraries you may define it inline, e.g. using `TypeDI`:\n\n```typescript\nuseContainer<TContext>(({ context }) => Container.of(context.requestId));\n```\n\nFor some other advanced libraries, you might need to create an instance of the container, place it in the context object and then retrieve it in `useContainer` getter function:\n\n```typescript\nuseContainer<TContext>(({ context }) => context.container);\n```\n\nThe tricky part is where the `context.requestId` comes from. Unfortunately, you need to provide it manually using hooks that are exposed by HTTP GraphQL middlewares like `express-graphql`, `apollo-server` or `graphql-yoga`.\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nYou 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.\n\nUnfortunately, Apollo Server doesn't have the \"document middlewares\" feature yet, so some dirty tricks are needed to do the cleanup.\nExample using `TypeDI` and `apollo-server` with the `formatResponse` method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  formatResponse: (response: any, { context }: ResolverData<Context>) => {\n    // remember to dispose the scoped container to prevent memory leaks\n    Container.reset(context.requestId);\n    return response;\n  },\n});\n```\n\nAnd basically that's it! The configuration of container is done and TypeGraphQL will be able to use different instances of resolvers for each request.\n\nThe only thing that left is the container configuration - you need to check out the docs for your container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup a lifetime of the injectable objects (transient, scoped or singleton).\n\n**Be aware** that some libraries (like `TypeDI`) by default creates new instances for every scoped container, so you might experience a **significant grow of a memory usage** and a some decrease in query resolving speed, so please be careful with using this feature!\n\n### Example\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/emit-schema.md",
    "content": "---\ntitle: Emitting schema SDL\nid: version-0.16.0-emit-schema\noriginal_id: emit-schema\n---\n\nThe TypeGraphQL main feature is creating schema using only TypeScript's classes and decorators. However, sometimes we might need the schema to be printed into a `schema.gql` file and there are a plenty of reasons for that. Mainly, 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 kinda 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 GraphiQL or GraphQL Playground.\n\nTo accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways. The first one is 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 a path and the file name where the schema definition should be written.\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // automatically create `schema.gql` file with schema definition\n  // in project's working directory\n  emitSchemaFile: true,\n  // or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"snapshots/schema\", \"schema.gql\"),\n});\n```\n\nSecond way to emit schema definition file is by doing it manually in a programmatic way. All you need to do is to use `emitSchemaDefinitionFile` function or it's sync version (`emitSchemaDefinitionFileSync`) and pass the selected path to it, along with the schema object. You can use this i.a. 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.\n\n```typescript\nimport { emitSchemaDefinitionFile, buildSchema } from \"type-graphql\";\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.gql\", schema);\n});\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/enums.md",
    "content": "---\ntitle: Enums\nid: version-0.16.0-enums\noriginal_id: enums\n---\n\nNowadays almost all typed languages have support for enumerated types, including TypeScript.\nEnums allow to limit the range of possible variable's values to a set of predefined constants, which make it easier to document intent.\n\nGraphQL also has enum type support, so `TypeGraphQL` allows you to use TypeScript enums in your GraphQL schema.\n\n## Usage\n\nFirst of all, you need to create a TypeScript enum.\nIt 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:\n\n```typescript\nenum Direction {\n  Up,\n  Down,\n  Left,\n  Right,\n}\n// or\nenum Direction {\n  Up = \"UP\",\n  Down = \"DOWN\",\n  Left = \"LEFT\",\n  Right = \"RIGHT\",\n}\n```\n\nTo tell TypeGraphQL about your enum, you would ideally mark the enums with `@GraphQLEnumType()` decorator. However, TypeScript's decorators only works 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:\n\n```typescript\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // this one is mandatory\n  description: \"The basic directions\", // this one is optional\n});\n```\n\nThe 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:\n\n```typescript\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // it's very important\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, you can use your enum directly in your code 😉\n\n```typescript\nclass Resolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // it will never be hitten ;)\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.16.0-examples\noriginal_id: examples\n---\n\nOn the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple examples showing how to use different TypeGraphQL features and how well it integrates with 3rd party libraries.\n\nAll examples has a `examples.gql` file with sample queries/mutations/subscriptions that you can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/enums-and-unions)\n- [Interfaces and types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/interfaces-inheritance)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/redis-subscriptions)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/resolvers-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/automatic-validation)\n- [Middlewares](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/middlewares)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/typeorm-lazy-relations)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/apollo-engine)\n\n_\\* Note that you need to edit the TypeORM examples `index.ts` with credentials to your local database_\n\n_\\*\\* Note that you need to provide `APOLLO_ENGINE_API_KEY` env variable with your own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\nid: version-0.16.0-faq\noriginal_id: faq\n---\n\n## Resolvers\n\n### Should I implement a field's resolver as a object type's getter, method or as a resolver class's method?\n\nIt really depends on various factors:\n\n- if your resolver need access only to the root/object value - use a getter\n- if your field has arguments\n  - and need to perform side effects (like db call) - use resolver class's method (leverage dependency injection mechanism)\n  - otherwise - use object type's methods (pure function, calculate based on object value and arguments)\n- if you want to separate business logic from type definition - use resolver class's method\n\n### Is there any global error handler to catch the error from resolver or a service?\n\nYou can use middlewares for this purpose - just wrap `await next()` in try-catch block and do the magic. Then register it as a first global middleware.\n\n### I got error like `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`. Why?\n\nThis error shows when your resolver (query, mutation, field) type is an interface/union and you return a plain object from it.\nIn this case you have to return an instance of the selected object type class in your resolvers.\nOtherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly.\n\n## Bootstrapping\n\n### Should I use array of manually imported resolver classes or use a glob path string?\n\nUsing path to resolver module files force you to structure yours project folders or constantly name files with prefix/suffix.\nWhen you have several dozen of resolver classes, it might be easier than always remember about importing and registering each new class.\n\n### I got error like `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`. How to fix that?\n\nThis error happens mostly when you have more than one version of `graphql-js` in your project.\nIn most cases it means that one of your dependencies has a dependency on different version of `graphql-js`, e.g. you use or TypeGraphQL uses `v14.0.2` but `apollo-server-express` depends on `v0.13.2`.\nYou can print the dependency tree by running `npm ls graphql` (or yarn's equivalent) to find the faulty dependencies.\nThen you have to update or downgrade them until they all match the semver on `graphql`, like `^14.0.0`.\nYou may also need to flatten your dependencies, so that they all will share a single instance of `graphql` module in `node_modules` directory - to achieve this, just run `npm dedupe` (or yarn's equivalent).\n\nThe same rule goes to the error like `node_modules/type-graphql/node_modules/@types/graphql/type/schema\").GraphQLSchema' is not assignable to type 'import(\"node_modules/@types/graphql/type/schema\").GraphQLSchema'`.\nIn that case you have to do the same checks but for the `@types/graphql` module in your dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate real `GraphQLInputType` and should be used when you want to have nested object in args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When I have to use the `() => [ItemType]` syntax?\n\nYou should use `[ItemType]` syntax every time when your field type is array or you return array from query/mutation.\n\nEven if you technically can omit the array notation (when the base type is not `Promise`) and provide only the type of array item (e.g. `@Field(() => ItemType) field: ItemType[]`) - it's better to be consistent with other annotations by explicit defining the type.\n\n### How can I define the two-dimension array (nested arrays, array of arrays)?\n\nUnfortunately, [GraphQL spec doesn't support 2D arrays](https://github.com/graphql/graphql-spec/issues/423), so you can't just use `data: [[Float]]` as a GraphQL type.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### In many cases I have a situation where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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 is appropriate for use as an input argument.\nHowever if you have only simple fields in your class definition, you can reuse the code between InputType and ObjectType - just decorate the ObjectType class with `@InputType`. But remember to set a new name of the type in decorator parameter:\n\n```typescript\n@ObjectType() // name inferred to `Person`\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-0.16.0-getting-started\noriginal_id: getting-started\n---\n\nTo explore all powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundations of our API.\n\n## Types\n\nWe want to get equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules when to use `nullable`, `array` and others are described in [fields and types docs](types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use `@Authorized()` decorator to restrict access only for authorized users or the one that fulfil the roles requirements.\nThe detailed rules when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md).\n\n## Inputs and arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```typescript\n@InputType()\nclass NewRecipeDataInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @MaxArraySize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` or `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform fields validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that we have to do is to actually build the schema from TypeGraphQL definition. We use `buildSchema` function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully working GraphQL schema!\nIf we print it, we would receive exactly this:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nIf 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/interfaces-and-inheritance.md",
    "content": "---\ntitle: Interfaces and inheritance\nid: version-0.16.0-interfaces-and-inheritance\noriginal_id: interfaces-and-inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\n## Interfaces\n\nTypeScript 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.\n\nLuckily, 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.\n\nSo, 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nThen we can use this \"interface\" in object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do it by passing the param `({ implements: IPerson })` to the decorator. If we implemented more interfaces, we would pass the array of interfaces, like `({ implements: [IPerson, IAnimal, IMachine] })`.\n\nWe 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.\n\nBe 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.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - don't repeat yourself - which tells about avoiding redundancy in our code.\n\nWhile 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:\n\n```typescript\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```typescript\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```typescript\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolvers inheritance\n\nThe 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.\n\nAs we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```typescript\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt'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.\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nThen 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nAfter that we can create a specific resolver class that will extend the base resolver class:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutation in our resolver class, just like always:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will be working correctly.\n\nBe 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.\n\n## Examples\n\nMore 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).\n\nFor more advanced resolvers inheritance example, please go to [the example folder](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/resolvers-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\nid: version-0.16.0-introduction\noriginal_id: introduction\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable, by defining the schema using only classes and a bit of decorators magic.\nExample object type:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL API quickly & easily!\n\n## Why?\n\nAs I mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to make.\n\nFirst, 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.:\n\n```typescript\nexport const recipesResolver: GraphQLFieldResolver<void, Context, RecipesArgs> = async (\n  _,\n  args,\n) => {\n  // our business logic, e.g.:\n  const repository = getRepository(Recipe);\n  return repository.find();\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/middlewares.md",
    "content": "---\ntitle: Middlewares and guards\nid: version-0.16.0-middlewares\noriginal_id: middlewares\n---\n\nMiddlewares are a piece of reusable code that can be easily attached to resolvers and fields. By using middlewares you can extract the common used code from your resolvers and then just declaratively attach it using decorator or even register globally.\n\n## Creating middlewares\n\n### What are middlewares?\n\nMiddlewares are a very powerful but also a bit complicated feature. Basically, they are functions that take 2 arguments:\n\n- resolver data - the same as for resolvers (`root`, `args`, `context`, `info`)\n- `next` function - used to control execution of next middlewares and the resolver to which they are attached\n\nYou 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.\n\nThanks to this it's really easy to perform some action not only before resolvers execution but also after that. So things like measuring execution time are really easy to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting execution result\n\nMiddlewares have also an ability to intercept the result of resolver execution. They are able not only to e.g. log it but they can also replace it with a new value:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt might be not very useful from this library users perspective but that feature was mainly introduced for plugins system and 3rd-party libs integration. Thanks to this, it's possible to e.g. wrap the returned object with lazy-relation wrapper that will automatically fetch relations from database on demand under the hood.\n\n### Simple middlewares\n\nIf you only want to do something only before action, like log the access to the resolver, you can just place `return next()` statement at the end of your middleware:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddlewares can also break the middlewares stack by not calling the `next` function. The result returned from the middleware will be used instead of calling the resolver and returning it's result.\n\nYou can also throw error in the middleware if the execution should be terminated and the error should be returned to the user, e.g. when resolver args are incorrect.\n\nThis way you can create a guard that will block an access to the resolver and prevent executing it or returning the data.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable middlewares\n\nSometimes the middleware has to be configurable, just like you pass `roles` array to the [`@Autorized()` decorator](authorization.md). In that case, you should create a simple middleware factory - a function that takes your configuration as a parameters and returns a middleware that use that provided value.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nBut remember to call this middleware with argument, e.g. `NumberInterceptor(3.0)` when you attach the middleware to a resolver!\n\n### Errors interceptors\n\nMiddlewares can also catch errors that were thrown during execution. This way you can easily log them and even filter what can't be returned to user:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based middlewares\n\nSometimes your middleware logic might be a bit complicated - it can communicate with database, write logs to file, etc., so you might want to test it. In that cases you can create class middleware that is able to take benefits of [dependency injection](dependency-injection.md) and easily mock a file logger or a database repository.\n\nAll you need to do is to implement a `MiddlewareInterface` - your class has to have the `use` method that conforms with `MiddlewareFn` signature. Below you can see how the defined earlier `LogAccess` middleware looks after the transformation:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use?\n\n### Attaching middlewares\n\nTo attach middlewares to resolver, place the `@UseMiddleware()` decorator above field or resolver declaration. It accepts an array of middlewares that will be called in the provided order. You can also pass them without array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nYou can also attach the resolver to `ObjectType` fields, the same way as with [`@Autorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global middlewares\n\nHowever, for common middlewares like measuring resolving time or catching errors, it might be a tedious work to place `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence in TypeGraphQL you can also register a global middleware that will be called for each query, mutation, subscription and field resolver. To do this, you have to use `globalMiddlewares` property of `buildSchema` configuration object:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom decorators\n\nIf 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:\n\n```typescript\nexport function ValidateArgs<T extends object>(schema: Schema<T>) {\n  return UseMiddleware(async ({ args }, next) => {\n    // here place your validation logic, e.g. based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-0.16.0-resolvers\noriginal_id: resolvers\n---\n\nBesides [declaring GraphQL's object types](types-and-fields.md), TypeGraphQL allows to create queries, mutations and field resolvers in an easy way - like a normal class methods, similar to REST controllers in frameworks like Java's `Spring`, .NET `Web API` or TypeScript's [`routing-controllers`](https://github.com/typestack/routing-controllers).\n\n## Queries and mutations\n\n### Resolvers classes\n\nFirst you have to create a resolver class and annotate it with `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nYou 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"title\", { nullable: true }) title?: string,\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nYou can define default values for optional fields in the `@Field()` decorator using a `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value and making the field nullable.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in [the validation docs](validation.md). You can also define a helper fields and methods for your args or input class.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  startIndex = skip;\n  endIndex = skip + take;\n}\n```\n\nThen all that left to do is to use the args class as the type of the method parameter.\nWe can use the destructuring syntax to have access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declarations will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL'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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nWe can also leverage TypeScript type checking system and ensure that we won't accidentally change the type of property by implementing `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nThen we can declare all the input fields we would need, using `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe might also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we can create the class method that become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety you can implement the `ResolverInterface<Recipe>` interface.\nIt'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\nand whether the first parameter of the method is the object type (`Recipe` class).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is a full sample implementation of the `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create the field resolvers inline in object type's class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolvers inheritance\n\nInheritance of resolver classes is an advanced topic covered in [inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are made up just for tutorial purposes.\nYou can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/scalars.md",
    "content": "---\ntitle: Scalars\nid: version-0.16.0-scalars\noriginal_id: scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field type:\n\n```typescript\n// import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases you will have to explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  get optionalInfo(): string | undefined {\n    // TS reflected type is `Object` :(\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- timestamp based (`\"timestamp\"`) - `1518037458374`\n- ISO format (`\"isoDate\"`) - `\"2018-02-07T21:04:39.573Z\"`\n\nThey are exported from `type-graphql` package as `GraphQLISODateScalar` and `GraphQLTimestampScalar`.\n\nBy default TypeGraphQL use the ISO date format, however you can change it in `buildSchema` options:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  dateScalarMode: \"timestamp\", // \"timestamp\" or \"isoDate\"\n});\n```\n\nThere's no need to explicitly declare the field type then:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\nIf 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).\n\n## Custom Scalars\n\nTypeGraphQL also support custom scalar types.\n\nFirst 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:\n\n```typescript\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  parseValue(value: string) {\n    return new ObjectId(value); // value from the client input variables\n  },\n  serialize(value: ObjectId) {\n    return value.toHexString(); // value sent to the client\n  },\n  parseLiteral(ast) {\n    if (ast.kind === Kind.STRING) {\n      return new ObjectId(ast.value); // value from the client query\n    }\n    return null;\n  },\n});\n```\n\nThen you can just use it in your field decorators:\n\n```typescript\n// import the earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // and explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, you can declare the association between the reflected property type and your scalars to automatically map them (no need to explicit type annotation!):\n\n```typescript\n@ObjectType()\nclass User {\n  @Field() // magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll you need to do is register the association map in the `buildSchema` options:\n\n```typescript\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-0.16.0-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries, and to perform writes with mutations.\nHowever, oftentimes clients want to get pushed updates from the server when data they care about changes.\nTo 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/).\n\n## Creating subscriptions\n\nSubscription resolvers are basically similar to [queries and mutation resolvers](resolvers.md) but a little bit more complicated.\n\nAt first, we create normal class method as always, this time annotated with `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which events from topics should trigger our subscription.\nThis function should return `boolean` or `Promise<boolean>`.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscriptions topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how to trigger the topics?\n\nThey might be triggered from external sources like a DB. We also can do this in mutations,\ne.g. when we modify some resource that clients want to receive notifications about the changes.\n\nSo, assuming we have this mutation for adding new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (easier mocking/stubbing), we can also inject only the `publish` method bound to selected topic.\nTo do this, we use `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to `NOTIFICATIONS` topic will be triggered while performing `addNewComment` mutation.\n\n## Using custom PubSub system\n\nBy default, TypeGraphQL use simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback that it will works correctly only when we have single instance (process) of our Node.js app.\n\nFor 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.\nIt might be e.g. Redis with [`graphql-redis-subscriptions`](https://github.com/davidyaha/graphql-redis-subscriptions) package.\n\nAll you need to do is to create an instance of PubSub according to package instruction and the provide it to TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating subscription server\n\nThe [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.\n\nFortunately, 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).\nThe `apollo-server` package has built-in subscriptions support using websockets, so it's working out of the box without any changes to our bootstrap config. However, if we want, we can provide the `subscriptions` property of config object:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done!. We have a working GraphQL subscription server on `/subscriptions`, along with a normal HTTP GraphQL server.\n\n## Examples\n\nYou can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/simple-subscriptions).\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/types-and-fields.md",
    "content": "---\ntitle: Types and fields\nid: version-0.16.0-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start with defining the example TypeScript class. It will represent our `Recipe` model with fields storing recipe's data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nFirst 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we need to declare which class properties should be mapped to GraphQL fields.\nTo do this, we use `@Field` decorator, which is also used to collect the metadata from TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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:\n\n- `@Field(type => [Rate])` (the recommended way - explicit `[ ]` syntax for Array)\n- `@Field(itemType => Rate)` (`array` is inferred from reflection - also ok but prone to error)\n\nWhy 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.\n\nFor 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.\n\nIn 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.\n\nIn the config object we can also provide `description` and `deprecationReason` for GraphQL schema purposes.\n\nSo after this changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich in result will generate following part of GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nAnalogously, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of GraphQL's SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote that if a field of an object type is purely calculable (eg. `averageRating` from `ratings` array) and you don't want to pollute the class signature, you can omit it and just implement the field resolver (described in [resolvers doc](resolvers.md)).\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.16.0-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nYou can read more about GraphQL union type in [official docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nThen we have to create the union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: [Movie, Actor], // array of object types classes\n});\n```\n\nAll that left to do is to use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, you have to explicitly use `SearchResultUnion` value in `@Query` decorator return type annotation.\nFor TS compile-time type safety you can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\nBe 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.\n\n**Et Voilà!** You can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.16.0/validation.md",
    "content": "---\ntitle: Arguments and inputs validation\nsidebar_label: Validation\nid: version-0.16.0-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nAnd 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.\n\n## How to use\n\nAt first, you have to decorate the input/arguments class with appropriate decorators from `class-validator`. So we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nand produce this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate your inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, if you need, you can disable it:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass default config object\n});\n```\n\nAnd if you need, you can still enable it per resolver's argument:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nYou can also pass `ValidatorOptions` object, for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups):\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote that by default `skipMissingProperties` setting of `class-validator` is set to `true` because GraphQL will check by itself whether the params/fields exists or not.\n\nGraphQL 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!\n\n## Response to the client\n\nWhen client send incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`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):\n\n```typescript\nimport { formatArgumentValidationError } from \"type-graphql\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  // pass error formatting helper to make validation errors works\n  formatError: formatArgumentValidationError,\n});\n```\n\nSo when `ArgumentValidationError` occurs, client will receive this JSON with nice `validationErrors` property:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"validationErrors\": [\n        {\n          \"target\": {\n            \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n          },\n          \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n          \"property\": \"title\",\n          \"children\": [],\n          \"constraints\": {\n            \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n          }\n        }\n      ]\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf course you can replace this with your own custom implementation of function that will transform `GraphQLError` with `ValidationError` array to the desired output format.\n\n## Example\n\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-0.17.0-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict access to some actions or reading some data only for specific group of users.\n\nIn express.js (and other Node.js framework) we use middlewares for this, like `passport.js` or the custom ones. However in GraphQL's resolvers architecture we don't have middlewares so we have to imperatively call the auth checking function and manually passing context data in each resolver, which might be quite tedious work.\n\nAnd that's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use?\n\nAt first, you need to use `@Authorized` decorator as a guard on a field or a query/mutation.\nExample object type's fields guards:\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nYou can leave the `@Authorized` decorator brackets empty or you can specify the roles that the user needs to have to get access to the field, query or mutation.\nBy default the roles are `string` but you can change it easily as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThis 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.\n\nSample query and mutations guards:\n\n```typescript\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data only for logged users\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Only for authed users!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop database ;)\";\n  }\n}\n```\n\nAuthed 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`.\n\nIn next step, you need to create your auth checker function. Its implementation may depends on your business logic:\n\n```typescript\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // here you can read user from context\n  // and check his permission in db against `roles` argument\n  // that comes from `@Authorized`, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or false if access denied\n};\n```\n\nThe second argument of `AuthChecker` generic type is `RoleType` - use it together with `@Authorized` decorator generic type.\n\nThe last step is to register the function while building the schema:\n\n```typescript\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // here we register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing authorization error.\n\n## Recipes\n\nYou can also use `TypeGraphQL` with JWT authentication. Example using `apollo-server-express`:\n\n```typescript\nimport express from \"express\";\nimport { ApolloServer, gql } from \"apollo-server-express\";\nimport * as jwt from \"express-jwt\";\n\nimport { schema } from \"../example/above\";\n\nconst app = express();\nconst path = \"/graphql\";\n\n// Create a GraphQL server\nconst server = new ApolloServer({\n  schema,\n  context: ({ req }) => {\n    const context = {\n      req,\n      user: req.user, // `req.user` comes from `express-jwt`\n    };\n    return context;\n  },\n});\n\n// Mount a jwt or other authentication middleware that is run before the GraphQL execution\napp.use(\n  path,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply the GraphQL server middleware\nserver.applyMiddleware({ app, path });\n\n// Launch the express server\napp.listen({ port: 4000 }, () =>\n  console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`),\n);\n```\n\nThen you can use standard, token based authorization in HTTP header like in classic REST API and take advantages of `TypeGraphQL` authorization mechanism.\n\n## Example\n\nYou can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-0.17.0-bootstrap\noriginal_id: bootstrap\n---\n\nAfter creating our resolvers, types 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 by HTTP server, WebSockets or even MQTT.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, you need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object you must provide a `resolvers` property, which can be an array of resolver classes:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SampleResolver],\n});\n```\n\nHowever, when there are several dozen of resolver classes, manual imports can be tedious.\nSo you can also provide an array of paths to resolver module files instead, which can include globs:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/modules/**/*.resolver.ts\", __dirname + \"/resolvers/**/*.ts\"],\n});\n```\n\nThere are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  });\n\n  // other initialization code, like creating http server\n}\n\nbootstrap(); // actually run the async function\n```\n\n## Create HTTP GraphQL endpoint\n\nIn 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):\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Building schema here\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    playground: true,\n  });\n\n  // Start the server\n  const { url } = await server.listen(PORT);\n  console.log(`Server is running, GraphQL Playground available at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install `apollo-server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL also provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt accepts the same `BuildSchemaOptions` like 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):\n\n```typescript\nimport { makeExecutableSchema } from \"graphql-tools\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```typescript\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ...other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ...the rest of `ApolloClient` initialization code\n```\n\nBe aware that some of the TypeGraphQL features (i.a. [query complexity](complexity.md)) might not work with `buildTypeDefsAndResolvers` approach because they use some low-level `graphql-js` features.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-0.17.0-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in client app\n\nSometimes 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.\n\nAs 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:\n\n```js\nplugins: [\n  // ...here are any other existing plugins that you already have\n  new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n    resource.request = resource.request.replace(/type-graphql/, \"type-graphql/dist/browser-shim\");\n  }),\n];\n```\n\nAlso, thanks to this your bundle will be much lighter as you don't embedded the whole TypeGraphQL library code in your app.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-0.17.0-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThe 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`.\n\nAll 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.\n\n## How to use?\n\nAt first, you need to pass `complexity` as an option to the decorator on a field/query/mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nYou can omit the `complexity` option if the complexity value is 1.\nYou 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.\n\nIn next step, you need to integrate `graphql-query-complexity` with your GraphQL server.\n\n```typescript\n// Create GraphQL server\nconst server = new GraphQLServer({ schema });\n\n// Configure server options\nconst serverOptions: Options = {\n  port: 4000,\n  endpoint: \"/graphql\",\n  playground: \"/playground\",\n  validationRules: req => [\n    queryComplexity({\n      // The maximum allowed query complexity, queries above this threshold will be rejected\n      maximumComplexity: 8,\n      // The query variables. This is needed because the variables are not available\n      // in the visitor of the graphql-js library\n      variables: req.query.variables,\n      // Optional callback function to retrieve the determined query complexity\n      // Will be invoked whether the query is rejected or not\n      // This can be used for logging or to implement rate limiting\n      onComplete: (complexity: number) => {\n        console.log(\"Query Complexity:\", complexity);\n      },\n      estimators: [\n        // Using fieldConfigEstimator is mandatory to make it work with type-graphql\n        fieldConfigEstimator(),\n        // This will assign each field a complexity of 1 if no other estimator\n        // returned a value. We can define the default value for fields not explicitly annotated\n        simpleEstimator({\n          defaultComplexity: 1,\n        }),\n      ],\n    }),\n  ],\n};\n\n// Start the server\nserver.start(serverOptions, ({ port, playground }) => {\n  console.log(\n    `Server is running, GraphQL Playground available at http://localhost:${port}${playground}`,\n  );\n});\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-0.17.0-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is to register 3rd party container. Example using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container;\n});\n```\n\nThen, your resolvers will be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nAnd the sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n### Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/using-container).\n\n## Scoped containers\n\nDependency injection is a really powerful pattern. But some advanced users may encounter the need of 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.\n\nTo register scoped container, you need to make some changes in the server bootstrapping config code.\nAt first you need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return instance of the container scoped to the request.\n\nFor simple container libraries you may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe tricky part is where the `context.requestId` comes from. Unfortunately, you need to provide it manually using hooks that are exposed by HTTP GraphQL middlewares like `express-graphql`, `apollo-server` or `graphql-yoga`.\n\nFor some other advanced libraries, you might need to create an instance of the container, place it in the context object and then retrieve it in `container` getter function:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nYou 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.\n\nUnfortunately, Apollo Server doesn't have the \"document middlewares\" feature yet, so some dirty tricks are needed to do the cleanup.\nExample using `TypeDI` and `apollo-server` with the `formatResponse` method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  formatResponse: (response: any, { context }: ResolverData<Context>) => {\n    // remember to dispose the scoped container to prevent memory leaks\n    Container.reset(context.requestId);\n    return response;\n  },\n});\n```\n\nAnd basically that's it! The configuration of container is done and TypeGraphQL will be able to use different instances of resolvers for each request.\n\nThe only thing that left is the container configuration - you need to check out the docs for your container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup a lifetime of the injectable objects (transient, scoped or singleton).\n\n> Be aware that some libraries (like `TypeDI`) by default creates new instances for every scoped container, so you might experience a **significant grow of a memory usage** and a some decrease in query resolving speed, so please be careful with using this feature!\n\n### Example\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/emit-schema.md",
    "content": "---\ntitle: Emitting schema SDL\nid: version-0.17.0-emit-schema\noriginal_id: emit-schema\n---\n\nThe TypeGraphQL main feature is creating schema using only TypeScript's classes and decorators. However, sometimes we might need the schema to be printed into a `schema.gql` file and there are a plenty of reasons for that. Mainly, 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 kinda 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 GraphiQL or GraphQL Playground. To accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways.\n\nThe 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.\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // automatically create `schema.gql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.gql\"),\n  // or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.gql\",\n    commentDescriptions: true,\n  },\n});\n```\n\nThe second way to emit schema definition file is by doing it manually in a programmatic way. All you need to do is to use `emitSchemaDefinitionFile` function (or it's sync version `emitSchemaDefinitionFileSync`) and pass the selected path to it, along with the schema object. You can use this i.a. 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.\n\n```typescript\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.gql\", schema);\n});\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/enums.md",
    "content": "---\ntitle: Enums\nid: version-0.17.0-enums\noriginal_id: enums\n---\n\nNowadays almost all typed languages have support for enumerated types, including TypeScript.\nEnums allow to limit the range of possible variable's values to a set of predefined constants, which make it easier to document intent.\n\nGraphQL also has enum type support, so `TypeGraphQL` allows you to use TypeScript enums in your GraphQL schema.\n\n## Usage\n\nFirst of all, you need to create a TypeScript enum.\nIt 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:\n\n```typescript\nenum Direction {\n  Up,\n  Down,\n  Left,\n  Right,\n}\n// or\nenum Direction {\n  Up = \"UP\",\n  Down = \"DOWN\",\n  Left = \"LEFT\",\n  Right = \"RIGHT\",\n}\n```\n\nTo tell TypeGraphQL about your enum, you would ideally mark the enums with `@GraphQLEnumType()` decorator. However, TypeScript's decorators only works 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:\n\n```typescript\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // this one is mandatory\n  description: \"The basic directions\", // this one is optional\n});\n```\n\nThe 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:\n\n```typescript\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // it's very important\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, you can use your enum directly in your code 😉\n\n```typescript\nclass Resolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // it will never be hitten ;)\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.17.0-examples\noriginal_id: examples\n---\n\nOn the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple examples showing how to use different TypeGraphQL features and how well it integrates with 3rd party libraries.\n\nAll examples has a `examples.gql` file with sample queries/mutations/subscriptions that you can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/interfaces-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/generic-types)\n- [Middlewares](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/middlewares)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/typeorm-lazy-relations)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/apollo-engine)\n\n_\\* Note that you need to edit the TypeORM examples `index.ts` with credentials to your local database_\n\n_\\*\\* Note that you need to provide `APOLLO_ENGINE_API_KEY` env variable with your own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\nid: version-0.17.0-faq\noriginal_id: faq\n---\n\n## Resolvers\n\n### Should I implement a field's resolver as a object type's getter, method or as a resolver class's method?\n\nIt really depends on various factors:\n\n- if your resolver need access only to the root/object value - use a getter\n- if your field has arguments\n  - and need to perform side effects (like db call) - use resolver class's method (leverage dependency injection mechanism)\n  - otherwise - use object type's methods (pure function, calculate based on object value and arguments)\n- if you want to separate business logic from type definition - use resolver class's method\n\n### Is there any global error handler to catch the error from resolver or a service?\n\nYou can use middlewares for this purpose - just wrap `await next()` in try-catch block and do the magic. Then register it as a first global middleware.\n\n### I got error like `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`. Why?\n\nThis error shows when your resolver (query, mutation, field) type is an interface/union and you return a plain object from it.\nIn this case you have to return an instance of the selected object type class in your resolvers.\nOtherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly.\n\n## Bootstrapping\n\n### Should I use array of manually imported resolver classes or use a glob path string?\n\nUsing path to resolver module files force you to structure yours project folders or constantly name files with prefix/suffix.\nWhen you have several dozen of resolver classes, it might be easier than always remember about importing and registering each new class.\n\n### I got error like `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`. How to fix that?\n\nThis error happens mostly when you have more than one version of `graphql-js` in your project.\nIn most cases it means that one of your dependencies has a dependency on different version of `graphql-js`, e.g. you use or TypeGraphQL uses `v14.0.2` but `apollo-server-express` depends on `v0.13.2`.\nYou can print the dependency tree by running `npm ls graphql` (or yarn's equivalent) to find the faulty dependencies.\nThen you have to update or downgrade them until they all match the semver on `graphql`, like `^14.0.0`.\nYou may also need to flatten your dependencies, so that they all will share a single instance of `graphql` module in `node_modules` directory - to achieve this, just run `npm dedupe` (or yarn's equivalent).\n\nThe same rule goes to the error like `node_modules/type-graphql/node_modules/@types/graphql/type/schema\").GraphQLSchema' is not assignable to type 'import(\"node_modules/@types/graphql/type/schema\").GraphQLSchema'`.\nIn that case you have to do the same checks but for the `@types/graphql` module in your dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate real `GraphQLInputType` and should be used when you want to have nested object in args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When I have to use the `() => [ItemType]` syntax?\n\nYou should use `[ItemType]` syntax every time when your field type is array or you return array from query/mutation.\n\nEven if you technically can omit the array notation (when the base type is not `Promise`) and provide only the type of array item (e.g. `@Field(() => ItemType) field: ItemType[]`) - it's better to be consistent with other annotations by explicit defining the type.\n\n### How can I define the two-dimension array (nested arrays, array of arrays)?\n\nUnfortunately, [GraphQL spec doesn't support 2D arrays](https://github.com/graphql/graphql-spec/issues/423), so you can't just use `data: [[Float]]` as a GraphQL type.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### In many cases I have a situation where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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 is appropriate for use as an input argument.\nHowever if you have only simple fields in your class definition, you can reuse the code between InputType and ObjectType - just decorate the ObjectType class with `@InputType`. But remember to set a new name of the type in decorator parameter:\n\n```typescript\n@ObjectType() // name inferred to `Person`\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/generic-types.md",
    "content": "---\ntitle: Generic types\nid: version-0.17.0-generic-types\noriginal_id: generic-types\n---\n\n[Types inheritance](inheritance.md) is a great way to reduce the 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).\n\nHence TypeGraphQL has also support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, the limited reflection capabilities of TypeScript doesn't allow for combining decorator with the standard generic classes. To achieve a behavior like the generic types, we will use the same class-creator pattern like the one described in [resolvers inheritance](inheritance.md) docs.\n\nSo we will start by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve a generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, we need to add proper decorators to the class - it might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent registering in schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, we can add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, we can use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    const response = new PaginatedUserResponse();\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return response;\n  }\n}\n```\n\nYou can also create a generic class without using `isAbstract` option or `abstract` keyword.\nBut types created with this kind of factory will be registered in schema, so it's not recommended to use this way to extend the types for adding some more fields.\n\nTo avoid generating schema errors about duplicated `PaginatedResponseClass` type names, you need to provide your own, unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, you have to provide a unique type name used in schema\n  @ObjectType({ name: `Paginated${TItemClass.name}Response` })\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, you can store the generated class in a variable. To be able to use it both as a runtime object and a type, you also have to create a type for this new class:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-0.17.0-getting-started\noriginal_id: getting-started\n---\n\n> Make sure that you've completed all the steps described in the [installation instruction](installation.md).\n\nTo explore all powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundations of our API.\n\n## Types\n\nWe want to get equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules when to use `nullable`, `array` and others are described in [fields and types docs](types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use `@Authorized()` decorator to restrict access only for authorized users or the one that fulfil the roles requirements.\nThe detailed rules when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md).\n\n## Inputs and arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```typescript\n@InputType()\nclass NewRecipeDataInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @MaxArraySize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` or `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform fields validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that we have to do is to actually build the schema from TypeGraphQL definition. We use `buildSchema` function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully working GraphQL schema!\nIf we print it, we would receive exactly this:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nIf 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-0.17.0-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence TypeGraphQL supports composing type definitions by extending the classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - don't repeat yourself - which tells about avoiding redundancy in our code.\n\nWhile 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:\n\n```typescript\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```typescript\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```typescript\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolvers inheritance\n\nThe 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.\n\nAs we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```typescript\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe aware that with some `tsconfig.json` settings (like `declarations: true`) 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.\n\nThis 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt'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.\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nThen 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nAfter that we can create a specific resolver class that will extend the base resolver class:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutation in our resolver class, just like always:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will be working correctly.\n\nBe 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.\n\n## Examples\n\nMore 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).\n\nFor more advanced resolvers inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/resolvers-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/installation.md",
    "content": "---\ntitle: Installation\nid: version-0.17.0-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure TypeScript configuration for our project.\n\n> #### Prerequisites\n>\n> Before you begin, make sure your development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, you have to install the main package, as well as the [`graphql-js`](https://github.com/graphql/graphql-js) (and it's typings) which is a peer dependency of TypeGraphQL:\n\n```sh\nnpm i graphql @types/graphql type-graphql\n```\n\nAlso, the `reflect-metadata` shim is required to make the type reflection works:\n\n```sh\nnpm i reflect-metadata\n```\n\nPlease make sure to import it on top of your entry file (before you use/import `type-graphql` or your resolvers):\n\n```typescript\nimport \"reflect-metadata\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in `tsconfig.json` file of your project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`TypeGraphQL` is designed to work with Node.js 6, 8 and latest stable. It uses features from ES7 (ES2016) so you should set your `tsconfig.json` appropriately:\n\n```js\n{\n  \"target\": \"es2016\" // or newer if your node.js version supports this\n}\n```\n\nDue to using `graphql-subscription` dependency that rely on an `AsyncIterator`, you may also have to provide the `esnext.asynciterable` to the `lib` option:\n\n```json\n{\n  \"lib\": [\"es2016\", \"esnext.asynciterable\"]\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2016\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es2016\", \"esnext.asynciterable\"],\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-0.17.0-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to create interfaces which describes the contract that classes implementing them has to fulfill - hence TypeGraphQL supports defining GraphQL interfaces.\n\n## How to?\n\nTypeScript 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.\n\nLuckily, 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.\n\nSo, 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nThen we can use this \"interface\" in object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do it by passing the param `({ implements: IPerson })` to the decorator. If we implemented more interfaces, we would pass the array of interfaces, like `({ implements: [IPerson, IAnimal, IMachine] })`.\n\nWe 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.\n\nBe 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.\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\nid: version-0.17.0-introduction\noriginal_id: introduction\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable, by defining the schema using only classes and a bit of decorators magic.\nExample object type:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL API quickly & easily!\n\n## Why?\n\nAs I mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to make.\n\nFirst, 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.:\n\n```typescript\nexport const recipesResolver: GraphQLFieldResolver<void, Context, RecipesArgs> = async (\n  _,\n  args,\n) => {\n  // our business logic, e.g.:\n  const repository = getRepository(Recipe);\n  return repository.find();\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/middlewares.md",
    "content": "---\ntitle: Middlewares and guards\nid: version-0.17.0-middlewares\noriginal_id: middlewares\n---\n\nMiddlewares are a piece of reusable code that can be easily attached to resolvers and fields. By using middlewares you can extract the common used code from your resolvers and then just declaratively attach it using decorator or even register globally.\n\n## Creating middlewares\n\n### What are middlewares?\n\nMiddlewares are a very powerful but also a bit complicated feature. Basically, they are functions that take 2 arguments:\n\n- resolver data - the same as for resolvers (`root`, `args`, `context`, `info`)\n- `next` function - used to control execution of next middlewares and the resolver to which they are attached\n\nYou 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.\n\nThanks to this it's really easy to perform some action not only before resolvers execution but also after that. So things like measuring execution time are really easy to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting execution result\n\nMiddlewares have also an ability to intercept the result of resolver execution. They are able not only to e.g. log it but they can also replace it with a new value:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt might be not very useful from this library users perspective but that feature was mainly introduced for plugins system and 3rd-party libs integration. Thanks to this, it's possible to e.g. wrap the returned object with lazy-relation wrapper that will automatically fetch relations from database on demand under the hood.\n\n### Simple middlewares\n\nIf you only want to do something only before action, like log the access to the resolver, you can just place `return next()` statement at the end of your middleware:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddlewares can also break the middlewares stack by not calling the `next` function. The result returned from the middleware will be used instead of calling the resolver and returning it's result.\n\nYou can also throw error in the middleware if the execution should be terminated and the error should be returned to the user, e.g. when resolver args are incorrect.\n\nThis way you can create a guard that will block an access to the resolver and prevent executing it or returning the data.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable middlewares\n\nSometimes the middleware has to be configurable, just like you pass `roles` array to the [`@Authorized()` decorator](authorization.md). In that case, you should create a simple middleware factory - a function that takes your configuration as a parameters and returns a middleware that use that provided value.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nBut remember to call this middleware with argument, e.g. `NumberInterceptor(3.0)` when you attach the middleware to a resolver!\n\n### Errors interceptors\n\nMiddlewares can also catch errors that were thrown during execution. This way you can easily log them and even filter what can't be returned to user:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based middlewares\n\nSometimes your middleware logic might be a bit complicated - it can communicate with database, write logs to file, etc., so you might want to test it. In that cases you can create class middleware that is able to take benefits of [dependency injection](dependency-injection.md) and easily mock a file logger or a database repository.\n\nAll you need to do is to implement a `MiddlewareInterface` - your class has to have the `use` method that conforms with `MiddlewareFn` signature. Below you can see how the defined earlier `LogAccess` middleware looks after the transformation:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use?\n\n### Attaching middlewares\n\nTo attach middlewares to resolver, place the `@UseMiddleware()` decorator above field or resolver declaration. It accepts an array of middlewares that will be called in the provided order. You can also pass them without array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nYou can also attach the resolver to `ObjectType` fields, the same way as with [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global middlewares\n\nHowever, for common middlewares like measuring resolving time or catching errors, it might be a tedious work to place `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence in TypeGraphQL you can also register a global middleware that will be called for each query, mutation, subscription and field resolver. To do this, you have to use `globalMiddlewares` property of `buildSchema` configuration object:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom decorators\n\nIf 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:\n\n```typescript\nexport function ValidateArgs<T extends object>(schema: Schema<T>) {\n  return UseMiddleware(async ({ args }, next) => {\n    // here place your validation logic, e.g. based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-0.17.0-resolvers\noriginal_id: resolvers\n---\n\nBesides [declaring GraphQL's object types](types-and-fields.md), TypeGraphQL allows to create queries, mutations and field resolvers in an easy way - like a normal class methods, similar to REST controllers in frameworks like Java's `Spring`, .NET `Web API` or TypeScript's [`routing-controllers`](https://github.com/typestack/routing-controllers).\n\n## Queries and mutations\n\n### Resolvers classes\n\nFirst you have to create a resolver class and annotate it with `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nYou 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"title\", { nullable: true }) title?: string,\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nYou can define default values for optional fields in the `@Field()` decorator using a `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value and making the field nullable.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in [the validation docs](validation.md). You can also define a helper fields and methods for your args or input class.\n\n```typescript\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  startIndex = skip;\n  endIndex = skip + take;\n}\n```\n\nThen all that left to do is to use the args class as the type of the method parameter.\nWe can use the destructuring syntax to have access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declarations will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL'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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nWe can also leverage TypeScript type checking system and ensure that we won't accidentally change the type of property by implementing `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nThen we can declare all the input fields we would need, using `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe might also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we can create the class method that become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety you can implement the `ResolverInterface<Recipe>` interface.\nIt'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\nand whether the first parameter of the method is the object type (`Recipe` class).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is a full sample implementation of the `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create the field resolvers inline in object type's class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolvers inheritance\n\nInheritance of resolver classes is an advanced topic covered in [resolvers inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are made up just for tutorial purposes.\nYou can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/scalars.md",
    "content": "---\ntitle: Scalars\nid: version-0.17.0-scalars\noriginal_id: scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field type:\n\n```typescript\n// import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases you will have to explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  // TS reflected type is `Object` :(\n  get optionalInfo(): string | undefined {\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- timestamp based (`\"timestamp\"`) - `1518037458374`\n- ISO format (`\"isoDate\"`) - `\"2018-02-07T21:04:39.573Z\"`\n\nThey are exported from `type-graphql` package as `GraphQLISODateScalar` and `GraphQLTimestampScalar`.\n\nBy default TypeGraphQL use the ISO date format, however you can change it in `buildSchema` options:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  dateScalarMode: \"timestamp\", // \"timestamp\" or \"isoDate\"\n});\n```\n\nThere's no need to explicitly declare the field type then:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\nIf 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).\n\n## Custom Scalars\n\nTypeGraphQL also support custom scalar types.\n\nFirst 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:\n\n```typescript\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  parseValue(value: string) {\n    return new ObjectId(value); // value from the client input variables\n  },\n  serialize(value: ObjectId) {\n    return value.toHexString(); // value sent to the client\n  },\n  parseLiteral(ast) {\n    if (ast.kind === Kind.STRING) {\n      return new ObjectId(ast.value); // value from the client query\n    }\n    return null;\n  },\n});\n```\n\nThen you can just use it in your field decorators:\n\n```typescript\n// import the earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // and explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, you can declare the association between the reflected property type and your scalars to automatically map them (no need to explicit type annotation!):\n\n```typescript\n@ObjectType()\nclass User {\n  @Field() // magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll you need to do is register the association map in the `buildSchema` options:\n\n```typescript\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-0.17.0-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries, and to perform writes with mutations.\nHowever, oftentimes clients want to get pushed updates from the server when data they care about changes.\nTo 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/).\n\n## Creating subscriptions\n\nSubscription resolvers are basically similar to [queries and mutation resolvers](resolvers.md) but a little bit more complicated.\n\nAt first, we create normal class method as always, this time annotated with `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which events from topics should trigger our subscription.\nThis function should return `boolean` or `Promise<boolean>`.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscriptions topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how to trigger the topics?\n\nThey might be triggered from external sources like a DB. We also can do this in mutations,\ne.g. when we modify some resource that clients want to receive notifications about the changes.\n\nSo, assuming we have this mutation for adding new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (easier mocking/stubbing), we can also inject only the `publish` method bound to selected topic.\nTo do this, we use `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to `NOTIFICATIONS` topic will be triggered while performing `addNewComment` mutation.\n\n## Using custom PubSub system\n\nBy default, TypeGraphQL use simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback that it will works correctly only when we have single instance (process) of our Node.js app.\n\nFor 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.\nIt might be e.g. Redis with [`graphql-redis-subscriptions`](https://github.com/davidyaha/graphql-redis-subscriptions) package.\n\nAll you need to do is to create an instance of PubSub according to package instruction and the provide it to TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating subscription server\n\nThe [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.\n\nFortunately, 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).\nThe `apollo-server` package has built-in subscriptions support using websockets, so it's working out of the box without any changes to our bootstrap config. However, if we want, we can provide the `subscriptions` property of config object:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done!. We have a working GraphQL subscription server on `/subscriptions`, along with a normal HTTP GraphQL server.\n\n## Examples\n\nYou can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/simple-subscriptions).\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/types-and-fields.md",
    "content": "---\ntitle: Types and fields\nid: version-0.17.0-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start with defining the example TypeScript class. It will represent our `Recipe` model with fields storing recipe's data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nFirst 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we need to declare which class properties should be mapped to GraphQL fields.\nTo do this, we use `@Field` decorator, which is also used to collect the metadata from TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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:\n\n- `@Field(type => [Rate])` (the recommended way - explicit `[ ]` syntax for Array)\n- `@Field(itemType => Rate)` (`array` is inferred from reflection - also ok but prone to error)\n\nWhy 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.\n\nFor 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.\n\nIn 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.\n\nIn the config object we can also provide `description` and `deprecationReason` for GraphQL schema purposes.\n\nSo after this changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich in result will generate following part of GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nAnalogously, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of GraphQL's SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote that if a field of an object type is purely calculable (eg. `averageRating` from `ratings` array) and you don't want to pollute the class signature, you can omit it and just implement the field resolver (described in [resolvers doc](resolvers.md)).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.17.0-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nYou can read more about GraphQL union type in [official docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nThen we have to create the union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: [Movie, Actor], // array of object types classes\n});\n```\n\nAll that's left to do is to use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, you have to explicitly use `SearchResultUnion` value in `@Query` decorator return type annotation.\nFor TS compile-time type safety you can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\nBe 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.\n\n**Et Voilà!** You can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.0/validation.md",
    "content": "---\ntitle: Arguments and inputs validation\nsidebar_label: Validation\nid: version-0.17.0-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nAnd 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.\n\n## How to use\n\nAt first, you have to decorate the input/arguments class with appropriate decorators from `class-validator`. So we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nand produce this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate your inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, if you need, you can disable it:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass default config object\n});\n```\n\nAnd if you need, you can still enable it per resolver's argument:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nYou can also pass `ValidatorOptions` object, for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups):\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote that by default `skipMissingProperties` setting of `class-validator` is set to `true` because GraphQL will check by itself whether the params/fields exists or not.\n\nGraphQL 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!\n\n## Response to the client\n\nWhen client send incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy default, the `apollo-server` package from [bootstrap guide](bootstrap.md) will format the error to match with the `GraphQLFormattedError` interface. So when `ArgumentValidationError` occurs, client will receive this JSON with nice `validationErrors` property inside `extensions.exception`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf course you can also create your own custom implementation of the `formatError` function provided to `ApolloServer` config options which will transform the `GraphQLError` with `ValidationError` array to the desired output format (e.g. `extensions.code = \"ARGUMENT_VALIDATION_ERROR\"`).\n\n## Example\n\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-0.17.1-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```typescript\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```typescript\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // here we can read the user from context\n  // and check his permission in the db against the `roles` argument\n  // that comes from the `@Authorized` decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or false if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nThe last step is to register the function while building the schema:\n\n```typescript\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // here we register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `apollo-server-express`:\n\n```typescript\nimport express from \"express\";\nimport { ApolloServer, gql } from \"apollo-server-express\";\nimport * as jwt from \"express-jwt\";\n\nimport { schema } from \"../example/above\";\n\nconst app = express();\nconst path = \"/graphql\";\n\n// Create a GraphQL server\nconst server = new ApolloServer({\n  schema,\n  context: ({ req }) => {\n    const context = {\n      req,\n      user: req.user, // `req.user` comes from `express-jwt`\n    };\n    return context;\n  },\n});\n\n// Mount a jwt or other authentication middleware that is run before the GraphQL execution\napp.use(\n  path,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply the GraphQL server middleware\nserver.applyMiddleware({ app, path });\n\n// Launch the express server\napp.listen({ port: 4000 }, () =>\n  console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`),\n);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-0.17.1-bootstrap\noriginal_id: bootstrap\n---\n\nAfter 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.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object you must provide a `resolvers` property, which can be an array of resolver classes:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SampleResolver],\n});\n```\n\nHowever, when there are several resolver classes, manual imports can be cumbersome.\nSo we can also provide an array of paths to resolver module files instead, which can include globs:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/modules/**/*.resolver.{ts,js}\", __dirname + \"/resolvers/**/*.{ts,js}\"],\n});\n```\n\nThere are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [__dirname + \"/**/*.resolver.{ts,js}\"],\n  });\n\n  // other initialization code, like creating http server\n}\n\nbootstrap(); // actually run the async function\n```\n\n## Create an HTTP GraphQL endpoint\n\nIn 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):\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Building schema here\n\n  // Create the GraphQL server\n  const server = new ApolloServer({\n    schema,\n    playground: true,\n  });\n\n  // Start the server\n  const { url } = await server.listen(PORT);\n  console.log(`Server is running, GraphQL Playground available at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install the `apollo-server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt 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):\n\n```typescript\nimport { makeExecutableSchema } from \"graphql-tools\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```typescript\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ...other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ...the rest of `ApolloClient` initialization code\n```\n\nBe 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-0.17.1-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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`, 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:\n\n```js\nplugins: [\n  // ...here are any other existing plugins that we already have\n  new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n    resource.request = resource.request.replace(/type-graphql/, \"type-graphql/dist/browser-shim\");\n  }),\n];\n```\n\nThanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-0.17.1-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the GraphQL server.\n\n```typescript\n// Create GraphQL server\nconst server = new GraphQLServer({ schema });\n\n// Configure server options\nconst serverOptions: Options = {\n  port: 4000,\n  endpoint: \"/graphql\",\n  playground: \"/playground\",\n  validationRules: req => [\n    queryComplexity({\n      // The maximum allowed query complexity, queries above this threshold will be rejected\n      maximumComplexity: 8,\n      // The query variables. This is needed because the variables are not available\n      // in the visitor of the graphql-js library\n      variables: req.query.variables,\n      // Optional callback function to retrieve the determined query complexity\n      // Will be invoked whether the query is rejected or not\n      // This can be used for logging or to implement rate limiting\n      onComplete: (complexity: number) => {\n        console.log(\"Query Complexity:\", complexity);\n      },\n      estimators: [\n        // Using fieldConfigEstimator is mandatory to make it work with type-graphql\n        fieldConfigEstimator(),\n        // This will assign each field a complexity of 1 if no other estimator\n        // returned a value. We can define the default value for fields not explicitly annotated\n        simpleEstimator({\n          defaultComplexity: 1,\n        }),\n      ],\n    }),\n  ],\n};\n\n// Start the server\nserver.start(serverOptions, ({ port, playground }) => {\n  console.log(\n    `Server is running, GraphQL Playground available at http://localhost:${port}${playground}`,\n  );\n});\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-0.17.1-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container. Example using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container;\n});\n```\n\nOur resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n### Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/using-container).\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nWe 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.\n\nUnfortunately, Apollo Server doesn't have a \"document middleware\" feature yet, so some dirty tricks are needed to do the cleanup.\nExample using `TypeDI` and `apollo-server` with the `formatResponse` method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  formatResponse: (response: any, { context }: ResolverData<Context>) => {\n    // remember to dispose the scoped container to prevent memory leaks\n    Container.reset(context.requestId);\n    return response;\n  },\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n### Example\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\nid: version-0.17.1-emit-schema\noriginal_id: emit-schema\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // automatically create `schema.gql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.gql\"),\n  // or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.gql\",\n    commentDescriptions: true,\n  },\n});\n```\n\nThe 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.\n\n```typescript\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.gql\", schema);\n});\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/enums.md",
    "content": "---\ntitle: Enums\nid: version-0.17.1-enums\noriginal_id: enums\n---\n\nNowadays 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.\n\nGraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema.\n\n## Usage\n\nLet'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:\n\n```typescript\nenum Direction {\n  Up,\n  Down,\n  Left,\n  Right,\n}\n// or\nenum Direction {\n  Up = \"UP\",\n  Down = \"DOWN\",\n  Left = \"LEFT\",\n  Right = \"RIGHT\",\n}\n```\n\nTo tell TypeGraphQL about our enum, we would ideally mark the enums with the `@GraphQLEnumType()` 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:\n\n```typescript\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // this one is mandatory\n  description: \"The basic directions\", // this one is optional\n});\n```\n\nThe 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:\n\n```typescript\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // it's very important\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, we can use our enum directly in our code 😉\n\n```typescript\nclass Resolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // it will never be hitten ;)\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.17.1-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/interfaces-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/generic-types)\n- [Middlewares](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/middlewares)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/typeorm-lazy-relations)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/typegoose)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/apollo-engine)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\nid: version-0.17.1-faq\noriginal_id: faq\n---\n\n## Resolvers\n\n### Should I implement a field resolver as an object type getter, a method or a resolver class method?\n\nThis depends on various factors:\n\n- if the resolver only needs access to the root/object value - use a getter\n- if the field has arguments\n  - and must perform side effects e.g. a database call - use a resolver class method and leverage the dependency injection mechanism\n  - otherwise, use object type methods (pure functions, calculations based on object values and arguments)\n- if the business logic must be separated from the type definition - use a resolver class method\n\n### Are there any global error handlers to catch errors from resolvers or services?\n\nUse middleware for this purpose - just wrap `await next()` in a try-catch block then register it as the first global middleware.\n\n### Why did I receive this error? `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`\n\nThis error occurs when the resolver (query, mutation, field) type is an interface/union and a plain object is returned from it.\nIn this case, what should be returned is an instance of the selected object type class in the resolver.\nOtherwise, `graphql-js` will not be able to correctly detect the underlying GraphQL type.\n\n## Bootstrapping\n\n### Should I use an array of manually imported resolver classes or a glob path string?\n\nUsing 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.\n\n### How do I fix this error? `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`\n\nThis error occurs mostly when there are more than one version of the `graphql-js` module in the project.\nIn 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`.\nWe can print the dependency tree by running `npm ls graphql` (or the yarn equivalent) to find the faulty dependencies.\nThen we should update or downgrade them until they all match the semver on `graphql`, e.g. `^14.0.0`.\nDependencies 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).\n\nThe 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'`.\nIn this case we repeat the same checks but for the `@types/graphql` module in our dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate a real `GraphQLInputType` type and should be used when we need a nested object in the args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When should I use the `() => [ItemType]` syntax?\n\nWe should use the `[ItemType]` syntax any time the field type or the return type is an array from a query or mutation.\n\nEven 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.\n\n### How can I define the two-dimension array (nested arrays, array of arrays)?\n\nUnfortunately, [GraphQL spec doesn't support 2D arrays](https://github.com/graphql/graphql-spec/issues/423), so you can't just use `data: [[Float]]` as a GraphQL type.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### Situations frequently arise where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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.\nHowever, 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:\n\n```typescript\n@ObjectType() // name inferred to `Person`\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-0.17.1-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\nStart by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent getting registered in the schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\nWe can also create a generic class without using the `isAbstract` option or the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, we have to provide a unique type name used in schema\n  @ObjectType({ name: `Paginated${TItemClass.name}Response` })\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-0.17.1-getting-started\noriginal_id: getting-started\n---\n\n> Make sure you've completed all the steps described in the [installation instructions](installation.md).\n\nTo explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundation of our API.\n\n## Types\n\nOur goal is to get the equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all its properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements.\nThe detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md).\n\n## Inputs and Arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```typescript\n@InputType()\nclass NewRecipeDataInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @MaxArraySize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` and `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully functional GraphQL schema!\nIf we print it, this is how it would look:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nFor more complicated cases, go to the [Examples section](examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-0.17.1-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```typescript\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```typescript\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```typescript\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```typescript\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt'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.\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```typescript\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver({ isAbstract: true })\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```typescript\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/installation.md",
    "content": "---\ntitle: Installation\nid: version-0.17.1-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> #### Prerequisites\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, we have to install the main package, as well as [`graphql-js`](https://github.com/graphql/graphql-js) (and it's typings) which is a peer dependency of TypeGraphQL:\n\n```sh\nnpm i graphql @types/graphql type-graphql\n```\n\nAlso, the `reflect-metadata` shim is required to make the type reflection work:\n\n```sh\nnpm i reflect-metadata\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```typescript\nimport \"reflect-metadata\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`TypeGraphQL` is designed to work with Node.js LTS (8, 10) and the latest stable releases. It uses features from ES7 (ES2016) so we should set our `tsconfig.json` file appropriately:\n\n```js\n{\n  \"target\": \"es2016\" // or newer if your node.js version supports this\n}\n```\n\nDue to using the `graphql-subscription` dependency that relies on an `AsyncIterator`, we may also have to provide the `esnext.asynciterable` to the `lib` option:\n\n```json\n{\n  \"lib\": [\"es2016\", \"esnext.asynciterable\"]\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2016\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es2016\", \"esnext.asynciterable\"],\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-0.17.1-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\n## How to\n\nTypeScript 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.\n\nLuckily, we can use an abstract class for this purpose. It behaves almost like an interface - it can't be \"newed\" but it can be implemented by the class - and it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat it like an interface, we can safely use it.\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then we use this \"interface\" in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nWe can also 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.\n\nBe 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\nid: version-0.17.1-introduction\noriginal_id: introduction\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic.\nExample object type:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL APIs quickly & easily!\n\n## Why?\n\nAs mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to take.\n\nFirst, 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.:\n\n```typescript\nexport const recipesResolver: GraphQLFieldResolver<void, Context, RecipesArgs> = async (\n  _,\n  args,\n) => {\n  // our business logic, e.g.:\n  const repository = getRepository(Recipe);\n  return repository.find();\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-0.17.1-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf we want to have a more descriptive and declarative API, we can also create custom decorators. They work in the same way as the reusable middleware function, however, in this case we need to return the `UseMiddleware` decorator function:\n\n```typescript\nexport function ValidateArgs<T extends object>(schema: Schema<T>) {\n  return UseMiddleware(async ({ args }, next) => {\n    // here place your validation logic, e.g. based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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 the id:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-0.17.1-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"title\", { nullable: true }) title?: string,\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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 and making the field nullable.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](validation.md). You can also define helper fields and methods for your args or input class.\n\n```typescript\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  startIndex = skip;\n  endIndex = skip + take;\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/scalars.md",
    "content": "---\ntitle: Scalars\nid: version-0.17.1-scalars\noriginal_id: scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field types:\n\n```typescript\n// import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  // TS reflected type is `Object` :(\n  get optionalInfo(): string | undefined {\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- timestamp based (`\"timestamp\"`) - `1518037458374`\n- ISO format (`\"isoDate\"`) - `\"2018-02-07T21:04:39.573Z\"`\n\nThey are exported from the `type-graphql` package as `GraphQLISODateScalar` and `GraphQLTimestampScalar`.\n\nBy default, TypeGraphQL uses the ISO date format, however you can change it in the `buildSchema` options:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  dateScalarMode: \"timestamp\", // \"timestamp\" or \"isoDate\"\n});\n```\n\nThere's no need then to explicitly declare the field type:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\n## Custom Scalars\n\nTypeGraphQL also supports custom scalar types!\n\nFirst 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:\n\n```typescript\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  parseValue(value: string) {\n    return new ObjectId(value); // value from the client input variables\n  },\n  serialize(value: ObjectId) {\n    return value.toHexString(); // value sent to the client\n  },\n  parseLiteral(ast) {\n    if (ast.kind === Kind.STRING) {\n      return new ObjectId(ast.value); // value from the client query\n    }\n    return null;\n  },\n});\n```\n\nThen we can just use it in our field decorators:\n\n```typescript\n// import the earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // and explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!):\n\n```typescript\n@ObjectType()\nclass User {\n  @Field() // magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll we need to do is register the association map in the `buildSchema` options:\n\n```typescript\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-0.17.1-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/simple-subscriptions).\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\nid: version-0.17.1-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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 two options available:\n\n- `@Field(type => [Rate])` (recommended, explicit `[ ]` syntax for Array types)\n- `@Field(itemType => Rate)` (`array` is inferred from reflection - also works but is prone to errors)\n\nWhy 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.\n\nFor 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.\n\nIn 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.\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.17.1-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL union type in the [official docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow let's create a union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: [Movie, Actor], // array of object types classes\n});\n```\n\nNow we can use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, we have to explicitly use the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\nBe 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.\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.1/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-0.17.1-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation by using the [`class-validator`](https://github.com/typestack/class-validator) library! We can use the awesomeness of decorators to 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).\n\n## How to use\n\nFirst we decorate the input/arguments class with the appropriate decorators from `class-validator`. So we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\n\nGraphQL 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!\n\n## Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n## Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/automatic-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.17.2-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/interfaces-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/generic-types)\n- [Middlewares](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/middlewares)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/typeorm-lazy-relations)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/typegoose)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/apollo-client)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-0.17.2-getting-started\noriginal_id: getting-started\n---\n\n> Make sure you've completed all the steps described in the [installation instructions](installation.md).\n\nTo explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundation of our API.\n\n## Types\n\nOur goal is to get the equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all its properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements.\nThe detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md).\n\n## Inputs and Arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```typescript\n@InputType()\nclass NewRecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @ArrayMaxSize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` and `@ArrayMaxSize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully functional GraphQL schema!\nIf we print it, this is how it would look:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nA lot of these topics are covered in Ben Awad's [Ben Awad](https://github.com/benawad)'s [TypeGraphQL video series](https://www.youtube.com/playlist?list=PLN3n1USn4xlma1bBu3Tloe4NyYn9Ko8Gs) on YouTube.\n\nFor more complicated cases, go to the [Examples section](examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-0.17.2-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Usage\n\nTypeScript 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.\n\nLuckily, we can use an abstract class for this purpose. It behaves almost like an interface - it can't be \"newed\" but it can be implemented by the class - and it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat it like an interface, we can safely use it.\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then we use this \"interface\" in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nWe can also 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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/v0.17.2/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\nid: version-0.17.2-introduction\noriginal_id: introduction\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic.\nExample object type:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL APIs quickly & easily!\n\n## Why?\n\nAs mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to take.\n\nFirst, 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.:\n\n```typescript\nexport const getRecipesResolver: GraphQLFieldResolver<void, Context, GetRecipesArgs> = async (\n  _,\n  args,\n  ctx,\n) => {\n  // common tasks repeatable for almost every resolver\n  const auth = Container.get(AuthService);\n  if (!auth.check(ctx.user)) {\n    throw new NotAuthorizedError();\n  }\n  await joi.validate(getRecipesSchema, args);\n  const repository = TypeORM.getRepository(Recipe);\n\n  // our business logic, e.g.:\n  return repository.find({ skip: args.offset, take: args.limit });\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\nid: version-0.17.2-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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 two options available:\n\n- `@Field(type => [Rate])` (recommended, explicit `[ ]` syntax for Array types)\n- `@Field(itemType => Rate)` (`array` is inferred from reflection - also works but is prone to errors)\n\nWhy 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.\n\nBy 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).\n\nSo 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.\n\nIn 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`.\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.2/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.17.2-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow let's create a union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: [Movie, Actor], // array of object types classes\n});\n```\n\nNow we can use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, we have to explicitly use the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: [Movie, Actor],\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.2/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-0.17.4-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  }\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.17.4-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/interfaces-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/generic-types)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/middlewares-custom-decorators)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/typeorm-lazy-relations)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/typegoose)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/apollo-client)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-0.17.4-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Usage\n\nTypeScript 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.\n\nLuckily, we can use an abstract class for this purpose. It behaves almost like an interface - it can't be \"newed\" but it can be implemented by the class - and it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat it like an interface, we can safely use it.\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then we use this \"interface\" in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nWe can also 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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/v0.17.4/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-0.17.4-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-0.17.4-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ args, context }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/simple-subscriptions).\n\nFor 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.4/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.4/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.17.4-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow let's create a union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: [Movie, Actor], // array of object types classes\n});\n```\n\nNow we can use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, we have to explicitly use the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: [Movie, Actor],\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.4/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-0.17.5-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```typescript\nasync function bootstrap() {\n  // ...build TypeGraphQL schema as always\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin that will allow for query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: () => ({\n          didResolveOperation({ request, document }) {\n            /**\n             * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server.\n             * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks.\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity.\n             */\n            const complexity = getComplexity({\n              // Our built schema\n              schema,\n              // To calculate query complexity properly,\n              // we have to check if the document contains multiple operations\n              // and eventually extract it operation from the whole query document.\n              query: request.operationName\n                ? separateOperations(document)[request.operationName]\n                : document,\n              // The variables for our GraphQL query\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity.\n              // If no estimator returns a value, an exception is raised.\n              estimators: [\n                // Using fieldConfigEstimator is mandatory to make it work with type-graphql.\n                fieldConfigEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value.\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n            // Here we can react to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached.\n            if (complexity > 20) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`,\n              );\n            }\n            // And here we can e.g. subtract the complexity point from hourly API calls limit.\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // ...start the server as always\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-0.17.5-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  }\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-0.17.5-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container. Example using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container,\n});\n```\n\nOur resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n### Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/using-container).\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `apollo-server` with plugins approach:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  plugins: [\n    {\n      requestDidStart: () => ({\n        willSendResponse(requestContext) {\n          // remember to dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.context.requestId);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n### Example\n\nFor a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/using-scoped-container).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/enums.md",
    "content": "---\ntitle: Enums\nid: version-0.17.5-enums\noriginal_id: enums\n---\n\nNowadays 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.\n\nGraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema.\n\n## Creating enum\n\nLet'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:\n\n```typescript\n// implicit value 0, 1, 2, 3\nenum Direction {\n  UP,\n  DOWN,\n  LEFT,\n  RIGHT,\n}\n\n// or explicit values\nenum Direction {\n  UP = \"up\",\n  DOWN = \"down\",\n  LEFT = \"left\",\n  RIGHT = \"right\",\n}\n```\n\nTo tell TypeGraphQL about our enum, we would ideally mark the enums with the `@GraphQLEnumType()` 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:\n\n```typescript\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // this one is mandatory\n  description: \"The basic directions\", // this one is optional\n});\n```\n\n## Using enum\n\nThe 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:\n\n```typescript\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // it's very important\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, we can use our enum directly in our code 😉\n\n```typescript\n@Resolver()\nclass SpriteResolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // it will never be hitten ;)\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n\n## Interoperability\n\nEnums 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`).\n\nSo 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.:\n\n```typescript\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-0.17.5-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/interfaces-inheritance)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/using-container)\n  - [scoped container](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/generic-types)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/middlewares-custom-decorators)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/typeorm-lazy-relations)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/typegoose)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/apollo-client)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\nid: version-0.17.5-faq\noriginal_id: faq\n---\n\n## Resolvers\n\n### Should I implement a field resolver as an object type getter, a method or a resolver class method?\n\nThis depends on various factors:\n\n- if the resolver only needs access to the root/object value - use a getter\n- if the field has arguments\n  - and must perform side effects e.g. a database call - use a resolver class method and leverage the dependency injection mechanism\n  - otherwise, use object type methods (pure functions, calculations based on object values and arguments)\n- if the business logic must be separated from the type definition - use a resolver class method\n\n### Are there any global error handlers to catch errors from resolvers or services?\n\nUse middleware for this purpose - just wrap `await next()` in a try-catch block then register it as the first global middleware.\n\n### Why did I receive this error? `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`\n\nThis error occurs when the resolver (query, mutation, field) type is an interface/union and a plain object is returned from it.\nIn this case, what should be returned is an instance of the selected object type class in the resolver.\nOtherwise, `graphql-js` will not be able to correctly detect the underlying GraphQL type.\n\n## Bootstrapping\n\n### Should I use an array of manually imported resolver classes or a glob path string?\n\nUsing 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.\n\n### How do I fix this error? `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`\n\nThis error occurs mostly when there are more than one version of the `graphql-js` module in the project.\nIn 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`.\nWe can print the dependency tree by running `npm ls graphql` (or the yarn equivalent) to find the faulty dependencies.\nThen we should update or downgrade them until they all match the semver on `graphql`, e.g. `^14.0.0`.\nDependencies 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).\n\nThe 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'`.\nIn this case we repeat the same checks but for the `@types/graphql` module in our dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate a real `GraphQLInputType` type and should be used when we need a nested object in the args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When should I use the `() => [ItemType]` syntax?\n\nWe should use the `[ItemType]` syntax any time the field type or the return type is an array from a query or mutation.\n\nEven 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.\n\n### How can I define a tuple?\n\nUnfortunately, [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.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### Situations frequently arise where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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.\nHowever, 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:\n\n```typescript\n@ObjectType() // name inferred to `Person`\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-0.17.5-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\nStart by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent getting registered in the schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\nWe can also create a generic class without using the `isAbstract` option or the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, we have to provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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.5/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-0.17.5-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Usage\n\nTypeScript 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.\n\nLuckily, we can use an abstract class for this purpose. It behaves almost like an interface - it can't be \"newed\" but it can be implemented by the class - and it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat it like an interface, we can safely use it.\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then we use this \"interface\" in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nWe can also 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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/v0.17.5/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-0.17.5-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-0.17.5-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ args, context }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/simple-subscriptions).\n\nFor 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.5/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\nid: version-0.17.5-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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 two options available:\n\n- `@Field(type => [Rate])` (recommended, explicit `[ ]` syntax for Array types)\n- `@Field(itemType => Rate)` (`array` is inferred from reflection - also works but is prone to errors)\n\nFor nested arrays however, the explicit `[ ]` notation is required to determine the depth of the array. `@Field(type => [[Int]])` would tell the compiler we expect an integer array of depth 2.\n\nWhy 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.\n\nBy 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).\n\nSo 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.\n\nIn 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`.\n\nFor 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]]!`\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.5/unions.md",
    "content": "---\ntitle: Unions\nid: version-0.17.5-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow let's create a union type from the object types above:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: () => [Movie, Actor], // function that returns array of object types classes\n});\n```\n\nNow we can use the union type in the query.\nNotice, that due to TypeScript's reflection limitation, we have to explicitly use the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor],\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-0.17.6/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-0.17.6-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  });\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v0.17.6/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-1.0.0-bootstrap\noriginal_id: bootstrap\n---\n\nAfter 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.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object we must provide a `resolvers` property, which can be an array of resolver classes:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nBe aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema.\n\nSo 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`:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\nimport { FirstObject } from \"../app/src/types\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n  // here provide all the types that are missing in schema\n  orphanedTypes: [FirstObject],\n});\n```\n\nIn 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<T>` constraints:\n\n```typescript\n// resolvers.ts\nexport const resolvers = [FirstResolver, SecondResolver] as const;\n\n// schema.ts\nimport { resolvers } from \"./resolvers\";\n\nconst schema = await buildSchema({ resolvers });\n```\n\nHowever, when there are several resolver classes, manual imports can be cumbersome.\nSo we can also provide an array of paths to resolver module files instead, which can include globs:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/modules/**/*.resolver.{ts,js}\", __dirname + \"/resolvers/**/*.{ts,js}\"],\n});\n```\n\n> 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.\n\nThere are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [__dirname + \"/**/*.resolver.{ts,js}\"],\n  });\n\n  // other initialization code, like creating http server\n}\n\nbootstrap(); // actually run the async function\n```\n\n## Create an HTTP GraphQL endpoint\n\nIn 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):\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Building schema here\n\n  // Create the GraphQL server\n  const server = new ApolloServer({\n    schema,\n    playground: true,\n  });\n\n  // Start the server\n  const { url } = await server.listen(PORT);\n  console.log(`Server is running, GraphQL Playground available at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install the `apollo-server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt 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):\n\n```typescript\nimport { makeExecutableSchema } from \"graphql-tools\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```typescript\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ...other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ...the rest of `ApolloClient` initialization code\n```\n\nBe 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-1.0.0-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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:\n\n```js\nmodule.exports = {\n  // ... the rest of the webpack config\n  plugins: [\n    // ... here are any other existing plugins that we already have\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/dist/browser-shim.js\");\n    }),\n  ];\n}\n```\n\nIn 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.\n\nHowever, 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:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"./node_modules/type-graphql/dist/browser-shim.ts\"]\n    }\n  }\n}\n```\n\nThanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-1.0.0-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```typescript\nasync function bootstrap() {\n  // ...build TypeGraphQL schema as always\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin that will allow for query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: () => ({\n          didResolveOperation({ request, document }) {\n            /**\n             * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server.\n             * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks.\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity.\n             */\n            const complexity = getComplexity({\n              // Our built schema\n              schema,\n              // To calculate query complexity properly,\n              // we have to check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // The GraphQL query document\n              query: document,\n              // The variables for our GraphQL query\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity.\n              // If no estimator returns a value, an exception is raised.\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql.\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value.\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n            // Here we can react to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached.\n            if (complexity > 20) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`,\n              );\n            }\n            // And here we can e.g. subtract the complexity point from hourly API calls limit.\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // ...start the server as always\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-1.0.0-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  });\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-1.0.0-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container,\n});\n```\n\nOur resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```typescript\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `apollo-server` with plugins approach:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  plugins: [\n    {\n      requestDidStart: () => ({\n        willSendResponse(requestContext) {\n          // remember to dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.context.requestId);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/using-container).\n\nFor a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/using-scoped-container).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/directives.md",
    "content": "---\ntitle: Directives\nid: version-1.0.0-directives\noriginal_id: directives\n---\n\n> 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.\n\nThough 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:\n\n```graphql\ntype Foo @auth(requires: USER) {\n  field: String!\n}\n\ntype Bar {\n  field: String! @auth(requires: USER)\n}\n```\n\nThat 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).\n\n**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator.\n\n## Usage\n\n### Declaring in schema\n\nBasically, we declare the usage of directives just like in SDL, with the `@` syntax:\n\n```typescript\n@Directive('@deprecated(reason: \"Use newField\")')\n```\n\nCurrently, you can use the directives only on object types, input types and their fields or fields resolvers, as well as queries, mutations and subscriptions.\n\nSo 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:\n\n```typescript\n@Directive(\"@auth(requires: USER)\")\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Directive(\"@auth(requires: USER)\")\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Directive(\"@auth(requires: ANY)\")\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Directive(\"@auth(requires: ADMIN)\")\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n> 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.\n\nAlso 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:\n\n```typescript\n@ObjectType()\nclass Foo {\n  @Directive(\"@lowercase\")\n  @Directive('@deprecated(reason: \"Use `newField`\")')\n  @Directive(\"@hasRole(role: Manager)\")\n  @Field()\n  bar: string;\n}\n```\n\n### Providing the implementation\n\nBesides declaring the usage of directives, you also have to register the runtime part of the used directives.\n\n> 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`.\n\nHere is an example using the [`graphql-tools`](https://github.com/apollographql/graphql-tools):\n\n```typescript\nimport { SchemaDirectiveVisitor } from \"graphql-tools\";\n\n// build the schema as always\nconst schema = buildSchemaSync({\n  resolvers: [SampleResolver],\n});\n\n// register the used directives implementations\nSchemaDirectiveVisitor.visitSchemaDirectives(schema, {\n  sample: SampleDirective,\n});\n```\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\nid: version-1.0.0-emit-schema\noriginal_id: emit-schema\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // automatically create `schema.gql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.gql\"),\n  // or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.gql\",\n    commentDescriptions: true,\n    sortedSchema: false, // by default the printed schema is sorted alphabetically\n  },\n});\n```\n\nThe 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.\n\n```typescript\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.gql\", schema);\n});\n```\n\n### Emit schema with custom directives\n\nCurrently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`.\n\nIf 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.\n\nBelow there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils):\n\n```typescript\nimport { GraphQLSchema, lexicographicSortSchema } from \"graphql\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport { outputFile } from \"type-graphql/dist/helpers/filesystem\";\n\nexport async function emitSchemaDefinitionWithDirectivesFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n): Promise<void> {\n  const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema));\n  await outputFile(schemaFilePath, schemaFileContent);\n}\n```\n\nThe usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`:\n\n```typescript\nconst schema = await buildSchema(/*...*/);\n\nawait emitSchemaDefinitionWithDirectivesFile(\"/path/to/folder/schema.gql\", schema);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-1.0.0-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/automatic-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/typeorm-lazy-relations)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/typegoose)\n- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/apollo-federation)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/apollo-client)\n- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/graphql-modules)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-1.0.0-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```typescript\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```typescript\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```typescript\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-1.0.0-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent getting registered in the schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```typescript\nexport default function PaginatedResponse<TItemsFieldValue>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ...other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```typescript\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `isAbstract` option or the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, we have to provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-1.0.0-getting-started\noriginal_id: getting-started\n---\n\n> Make sure you've completed all the steps described in the [installation instructions](installation.md).\n\nTo explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundation of our API.\n\n## Types\n\nOur goal is to get the equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all its properties and types:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```typescript\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements.\nThe detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md).\n\n## Inputs and Arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```typescript\n@InputType()\nclass NewRecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @ArrayMaxSize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` and `@ArrayMaxSize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ...creating express server or sth\n```\n\nEt voilà! Now we have fully functional GraphQL schema!\nIf we print it, this is how it would look:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nA 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.\n\nFor more complicated cases, go to the [Examples section](examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/installation.md",
    "content": "---\ntitle: Installation\nid: version-1.0.0-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> #### Prerequisites\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, 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:\n\n```sh\nnpm i graphql class-validator type-graphql\n```\n\nAlso, the `reflect-metadata` shim is required to make the type reflection work:\n\n```sh\nnpm i reflect-metadata\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```typescript\nimport \"reflect-metadata\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`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:\n\n```js\n{\n  \"target\": \"es2018\" // or newer if your node.js version supports this\n}\n```\n\nDue to using the `graphql-subscription` dependency that relies on an `AsyncIterator`, we may also have to provide the `esnext.asynciterable` to the `lib` option:\n\n```json\n{\n  \"lib\": [\"es2018\", \"esnext.asynciterable\"]\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2018\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es2018\", \"esnext.asynciterable\"],\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-1.0.0-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```typescript\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```typescript\n@ObjectType({ implements: [Person, Node] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & IPerson {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```typescript\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // here we provide such object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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.0.0/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-1.0.0-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/nestjs.md",
    "content": "---\ntitle: NestJS Integration\nsidebar_label: NestJS\nid: version-1.0.0-nestjs\noriginal_id: nestjs\n---\n\nTypeGraphQL provides some basic integration with NestJS by the [`typegraphql-nestjs` package](https://www.npmjs.com/package/typegraphql-nestjs).\n\nIt allows to use TypeGraphQL features while integrating with NestJS modules system and its dependency injector.\n\n## Overview\n\nThe usage is similar to the official `@nestjs/graphql` package.\nFirst you need to register your resolver classes in `providers` of the `@Module` :\n\n```typescript\n@Module({\n  providers: [RecipeResolver, RecipeService],\n})\nexport default class RecipeModule {}\n```\n\nThen you need to register the TypeGraphQL module in your root module - you can pass there all standard `buildSchema` options:\n\n```typescript\n@Module({\n  imports: [\n    TypeGraphQLModule.forRoot({\n      emitSchemaFile: true,\n      authChecker,\n      dateScalarMode: \"timestamp\",\n      context: ({ req }) => ({ currentUser: req.user }),\n    }),\n    RecipeModule,\n  ],\n})\nexport default class AppModule {}\n```\n\nAnd your `AppModule` is ready to use like with a standard NestJS approach.\n\n### Caveats\n\nFor now, this basic integration doesn't support other NestJS features like guards, interceptors, filters and pipes.\nTo achieve the same goals, you can use standard TypeGraphQL equivalents - middlewares, custom decorators, built-in authorization and validation.\n\n## Documentation and examples\n\nYou 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/).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/performance.md",
    "content": "---\ntitle: Performance\nid: version-1.0.0-performance\noriginal_id: performance\n---\n\n**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.\n\nWhile this enable easy and convenient development, it's sometimes a tradeoff in a performance.\n\n## Benchmarks\n\nTo 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.0.0/benchmarks).\n\nThe most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower.\n\n|                      | 25 000 array items | Deeply nested object |\n| -------------------- | :----------------: | :------------------: |\n| Standard TypeGraphQL |     1253.28 ms     |       45.57 μs       |\n| `graphql-js`         |     265.52 ms      |       24.22 μs       |\n\nIn 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.\n\n## Optimizations\n\nPromises 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`.\n\n| `graphql-js`    | 25 000 array items |\n| --------------- | :----------------: |\n| sync resolvers  |     265.52 ms      |\n| async resolvers |     512.61 ms      |\n\nTypeGraphQL 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.\n\nAlso, 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).\n\nThe 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!\n\n## Further performance tweaks\n\nWhen 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.:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField: string;\n\n  @Field({ simple: true })\n  publicFrequentlyQueriedField: SomeType;\n}\n```\n\nMoreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.:\n\n```typescript\n@ObjectType({ simpleResolvers: true })\nclass Post {\n  @Field()\n  title: string;\n\n  @Field()\n  createdAt: Date;\n\n  @Field()\n  isPublished: boolean;\n}\n```\n\nThis 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.0.0/benchmarks):\n\n|                                                                               | 25 000 array items |\n| ----------------------------------------------------------------------------- | :----------------: |\n| `graphql-js`                                                                  |     265.52 ms      |\n| Standard TypeGraphQL                                                          |     310.36 ms      |\n| TypeGraphQL with a global middleware                                          |     1253.28 ms     |\n| **TypeGraphQL with \"simpleResolvers\" applied <br> (and a global middleware)** |   **299.61 ms**    |\n\n> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature.\n\nBy 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.\n\nThat'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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/prisma.md",
    "content": "---\ntitle: Prisma Integration\nsidebar_label: Prisma\nid: version-1.0.0-prisma\noriginal_id: prisma\n---\n\nTypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma).\n\nIt 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.\n\n## Overview\n\nTo make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file:\n\n```sh\ngenerator typegraphql {\n  provider = \"typegraphql-prisma\"\n}\n```\n\nThen, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema:\n\n```typescript\nimport { resolvers } from \"@generated/type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  validate: false,\n});\n```\n\nSo we will be able to execute a complex query, that talks with the real database, in just a few minutes!\n\n```graphql\nquery GetSomeUsers {\n  users(where: { email: { contains: \"prisma\" } }, orderBy: { name: desc }) {\n    id\n    name\n    email\n    posts(take: 10, orderBy: { updatedAt: desc }) {\n      published\n      title\n      content\n    }\n  }\n}\n```\n\n## Documentation and examples\n\nTo 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/).\n\nThere also can be found the links to some examples and more detailed info about the installation and the configuration.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-1.0.0-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"title\", { nullable: true }) title?: string,\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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 and making the field nullable.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](validation.md).\n\nWe 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.\n\n```typescript\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/scalars.md",
    "content": "---\ntitle: Scalars\nid: version-1.0.0-scalars\noriginal_id: scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field types:\n\n```typescript\n// import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  // TS reflected type is `Object` :(\n  get optionalInfo(): string | undefined {\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- timestamp based (`\"timestamp\"`) - `1518037458374`\n- ISO format (`\"isoDate\"`) - `\"2018-02-07T21:04:39.573Z\"`\n\nThey are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp`.\n\nBy default, TypeGraphQL uses the ISO date format, however you can change it in the `buildSchema` options:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  dateScalarMode: \"timestamp\", // \"timestamp\" or \"isoDate\"\n});\n```\n\nThere's no need then to explicitly declare the field type:\n\n```typescript\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\n## Custom Scalars\n\nTypeGraphQL also supports custom scalar types!\n\nFirst 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:\n\n```typescript\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  serialize(value: unknown): string {\n    // check the type of received value\n    if (!(value instanceof ObjectId)) {\n      throw new Error(\"ObjectIdScalar can only serialize ObjectId values\");\n    }\n    return value.toHexString(); // value sent to the client\n  },\n  parseValue(value: unknown): ObjectId {\n    // check the type of received value\n    if (typeof value !== \"string\") {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(value); // value from the client input variables\n  },\n  parseLiteral(ast): ObjectId {\n    // check the type of received value\n    if (ast.kind !== Kind.STRING) {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(ast.value); // value from the client query\n  },\n});\n```\n\nThen we can just use it in our field decorators:\n\n```typescript\n// import the earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // and explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!):\n\n```typescript\n@ObjectType()\nclass User {\n  @Field() // magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll we need to do is register the association map in the `buildSchema` options:\n\n```typescript\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-1.0.0-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ args, context }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/simple-subscriptions).\n\nFor 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.0.0/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\nid: version-1.0.0-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```typescript\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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])`.\nFor 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.\n\nWhy 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.\n\nBy 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).\n\nSo 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.\n\nIn 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\"`.\n\nFor 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]]!`\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```typescript\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```typescript\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n\nBe 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.\n\nIn some case we may want to expose our classes or properties under a different types or fields name.\nTo accomplish this, we can use the `name` parameter or `name` property of decorator's options, e.g.:\n\n```typescript\n@ObjectType(\"ExternalTypeName\")\nclass InternalClassName {\n  @Field({ name: \"externalFieldName\" })\n  internalPropertyName: string;\n}\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/unions.md",
    "content": "---\ntitle: Unions\nid: version-1.0.0-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-1.0.0/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-1.0.0-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation by using the [`class-validator`](https://github.com/typestack/class-validator) library! We can use the awesomeness of decorators to 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).\n\n## How to use\n\nFirst we decorate the input/arguments class with the appropriate decorators from `class-validator`. So we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\n\nGraphQL 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!\n\nHowever, 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.\n\n## Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n## Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.0.0/examples/automatic-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.0/enums.md",
    "content": "---\ntitle: Enums\nid: version-1.1.0-enums\noriginal_id: enums\n---\n\nNowadays 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.\n\nGraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema.\n\n## Creating enum\n\nLet'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:\n\n```typescript\n// implicit value 0, 1, 2, 3\nenum Direction {\n  UP,\n  DOWN,\n  LEFT,\n  RIGHT,\n}\n\n// or explicit values\nenum Direction {\n  UP = \"up\",\n  DOWN = \"down\",\n  LEFT = \"left\",\n  RIGHT = \"right\",\n}\n```\n\nTo 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:\n\n```typescript\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // this one is mandatory\n  description: \"The basic directions\", // this one is optional\n});\n```\n\nIn 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.:\n\n```typescript\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n  SIDEWAYS = \"SIDEWAYS\",\n}\n\nregisterEnumType(Direction, {\n  name: \"Direction\",\n  description: \"The basic directions\",\n  valuesConfig: {\n    SIDEWAYS: {\n      deprecationReason: \"Replaced with Left or Right\",\n    },\n    RIGHT: {\n      description: \"The other left\",\n    },\n  },\n});\n```\n\nThis way, the additional info will be emitted in the GraphQL schema:\n\n```graphql\nenum Direction {\n  UP\n  DOWN\n  LEFT\n  \"\"\"\n  The other left\n  \"\"\"\n  RIGHT\n  SIDEWAYS @deprecated(reason: \"Replaced with Left or Right\")\n}\n```\n\n## Using enum\n\nThe 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:\n\n```typescript\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // it's very important\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, we can use our enum directly in our code 😉\n\n```typescript\n@Resolver()\nclass SpriteResolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // it will never be hitten ;)\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n\n## Interoperability\n\nEnums 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`).\n\nSo 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.:\n\n```typescript\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.0/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-1.1.0-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typeorm-lazy-relations)\n- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/mikro-orm)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typegoose)\n- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-federation)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-client)\n- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/graphql-modules)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.0/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-1.1.0-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validators) section.\n\n## `class-validator`\n\n### How to use\n\nFirst we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`.\nIt receives two parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`).\n\nThe `validate` function can be async and should return nothing (`void`) when validation passes or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validate` function for TypeGraphQL.\n\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...other options\n  validate: argValue => {\n    // call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/custom-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-1.1.1-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```typescript\nasync function bootstrap() {\n  // ...build TypeGraphQL schema as always\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin that will allow for query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: () => ({\n          didResolveOperation({ request, document }) {\n            /**\n             * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server.\n             * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks.\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity.\n             */\n            const complexity = getComplexity({\n              // Our built schema\n              schema,\n              // To calculate query complexity properly,\n              // we have to check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // The GraphQL query document\n              query: document,\n              // The variables for our GraphQL query\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity.\n              // If no estimator returns a value, an exception is raised.\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql.\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value.\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n            // Here we can react to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached.\n            if (complexity > 20) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`,\n              );\n            }\n            // And here we can e.g. subtract the complexity point from hourly API calls limit.\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // ...start the server as always\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-1.1.1-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  });\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-1.1.1-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container,\n});\n```\n\nOur resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```typescript\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `apollo-server` with plugins approach:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  plugins: [\n    {\n      requestDidStart: () => ({\n        willSendResponse(requestContext) {\n          // remember to dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.context.requestId);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/using-container).\n\nFor a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/using-scoped-container).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-1.1.1-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/typeorm-lazy-relations)\n- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/mikro-orm)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/typegoose)\n- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/apollo-federation)\n- [Apollo Engine (Apollo Cache Control) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/apollo-engine)\n- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/apollo-client)\n- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/graphql-modules)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n\n_\\*\\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-1.1.1-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```typescript\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```typescript\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```typescript\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-1.1.1-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent getting registered in the schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```typescript\nexport default function PaginatedResponse<TItemsFieldValue>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ...other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```typescript\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `isAbstract` option or the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, we have to provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-1.1.1-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```typescript\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```typescript\n@ObjectType({ implements: [Person, Node] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & IPerson {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```typescript\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // here we provide such object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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.1.1/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-1.1.1-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/performance.md",
    "content": "---\ntitle: Performance\nid: version-1.1.1-performance\noriginal_id: performance\n---\n\n**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.\n\nWhile this enable easy and convenient development, it's sometimes a tradeoff in a performance.\n\n## Benchmarks\n\nTo 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.1.1/benchmarks).\n\nThe most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower.\n\n|                      | 25 000 array items | Deeply nested object |\n| -------------------- | :----------------: | :------------------: |\n| Standard TypeGraphQL |     1253.28 ms     |       45.57 μs       |\n| `graphql-js`         |     265.52 ms      |       24.22 μs       |\n\nIn 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.\n\n## Optimizations\n\nPromises 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`.\n\n| `graphql-js`    | 25 000 array items |\n| --------------- | :----------------: |\n| sync resolvers  |     265.52 ms      |\n| async resolvers |     512.61 ms      |\n\nTypeGraphQL 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.\n\nAlso, 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).\n\nThe 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!\n\n## Further performance tweaks\n\nWhen 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.:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField: string;\n\n  @Field({ simple: true })\n  publicFrequentlyQueriedField: SomeType;\n}\n```\n\nMoreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.:\n\n```typescript\n@ObjectType({ simpleResolvers: true })\nclass Post {\n  @Field()\n  title: string;\n\n  @Field()\n  createdAt: Date;\n\n  @Field()\n  isPublished: boolean;\n}\n```\n\nThis 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.1.1/benchmarks):\n\n|                                                                               | 25 000 array items |\n| ----------------------------------------------------------------------------- | :----------------: |\n| `graphql-js`                                                                  |     265.52 ms      |\n| Standard TypeGraphQL                                                          |     310.36 ms      |\n| TypeGraphQL with a global middleware                                          |     1253.28 ms     |\n| **TypeGraphQL with \"simpleResolvers\" applied <br> (and a global middleware)** |   **299.61 ms**    |\n\n> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature.\n\nBy 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.\n\nThat'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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-1.1.1-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"title\", { nullable: true }) title?: string,\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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 and making the field nullable.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](validation.md).\n\nWe 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.\n\n```typescript\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-1.1.1-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: (root, args, context, info) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/simple-subscriptions).\n\nFor 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.1.1/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/unions.md",
    "content": "---\ntitle: Unions\nid: version-1.1.1-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-1.1.1/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-1.1.1-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validators) section.\n\n## `class-validator`\n\n### How to use\n\nFirst we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`.\nIt receives two parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`).\n\nThe `validate` function can be async and should return nothing (`void`) when validation passes or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validate` function for TypeGraphQL.\n\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...other options\n  validate: argValue => {\n    // call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v1.1.1/examples/custom-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-1.2.0-rc.1-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```typescript\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```typescript\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // here we can read the user from context\n  // and check his permission in the db against the `roles` argument\n  // that comes from the `@Authorized` decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or false if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  // inject dependency\n  constructor(private readonly userRepository: Repository<User>) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // use injected service\n    const user = this.userRepository.getById(userId);\n\n    // custom logic here, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```typescript\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // here we register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `apollo-server-express`:\n\n```typescript\nimport express from \"express\";\nimport { ApolloServer, gql } from \"apollo-server-express\";\nimport * as jwt from \"express-jwt\";\n\nimport { schema } from \"../example/above\";\n\nconst app = express();\nconst path = \"/graphql\";\n\n// Create a GraphQL server\nconst server = new ApolloServer({\n  schema,\n  context: ({ req }) => {\n    const context = {\n      req,\n      user: req.user, // `req.user` comes from `express-jwt`\n    };\n    return context;\n  },\n});\n\n// Mount a jwt or other authentication middleware that is run before the GraphQL execution\napp.use(\n  path,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply the GraphQL server middleware\nserver.applyMiddleware({ app, path });\n\n// Launch the express server\napp.listen({ port: 4000 }, () =>\n  console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`),\n);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-1.2.0-rc.1-bootstrap\noriginal_id: bootstrap\n---\n\nAfter 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.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object we must provide a `resolvers` property, which can be an array of resolver classes:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nBe aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema.\n\nSo 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`:\n\n```typescript\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\nimport { FirstObject } from \"../app/src/types\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n  // here provide all the types that are missing in schema\n  orphanedTypes: [FirstObject],\n});\n```\n\nIn 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<T>` constraints:\n\n```typescript\n// resolvers.ts\nexport const resolvers = [FirstResolver, SecondResolver] as const;\n\n// schema.ts\nimport { resolvers } from \"./resolvers\";\n\nconst schema = await buildSchema({ resolvers });\n```\n\nHowever, when there are several resolver classes, manual imports can be cumbersome.\nSo we can also provide an array of paths to resolver module files instead, which can include globs:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/modules/**/*.resolver.{ts,js}\", __dirname + \"/resolvers/**/*.{ts,js}\"],\n});\n```\n\n> 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.\n\nThere are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [__dirname + \"/**/*.resolver.{ts,js}\"],\n  });\n\n  // other initialization code, like creating http server\n}\n\nbootstrap(); // actually run the async function\n```\n\n## Create an HTTP GraphQL endpoint\n\nIn 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):\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Building schema here\n\n  // Create the GraphQL server\n  const server = new ApolloServer({\n    schema,\n    playground: true,\n  });\n\n  // Start the server\n  const { url } = await server.listen(PORT);\n  console.log(`Server is running, GraphQL Playground available at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install the `apollo-server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt 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):\n\n```typescript\nimport { makeExecutableSchema } from \"graphql-tools\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```typescript\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ...other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ...the rest of `ApolloClient` initialization code\n```\n\nThere's also a sync version of it - `buildTypeDefsAndResolversSync`:\n\n```typescript\nconst { typeDefs, resolvers } = buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-1.2.0-rc.1-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```typescript\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```typescript\nasync function bootstrap() {\n  // ...build TypeGraphQL schema as always\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin that will allow for query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: () => ({\n          didResolveOperation({ request, document }) {\n            /**\n             * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server.\n             * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks.\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity.\n             */\n            const complexity = getComplexity({\n              // Our built schema\n              schema,\n              // To calculate query complexity properly,\n              // we have to check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // The GraphQL query document\n              query: document,\n              // The variables for our GraphQL query\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity.\n              // If no estimator returns a value, an exception is raised.\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql.\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value.\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n            // Here we can react to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached.\n            if (complexity > 20) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`,\n              );\n            }\n            // And here we can e.g. subtract the complexity point from hourly API calls limit.\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // ...start the server as always\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-1.2.0-rc.1-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```typescript\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // here place your middleware code that uses custom decorator arguments\n\n    // e.g. validation logic based on schema using joi\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // custom decorator\n  @UseMiddleware(ResolveTime) // explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```typescript\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```typescript\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // calculate an object with info about requested fields\n    // based on GraphQL `info` parameter of the resolver and the level parameter\n    return fieldsMap;\n  });\n}\n```\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // here we place our custom decorator\n    // just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in our resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // our custom decorator that parses the fields from graphql query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-1.2.0-rc.1-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```typescript\nimport { buildSchema } from \"type-graphql\";\n// import your IoC container\nimport { Container } from \"typedi\";\n\nimport { SampleResolver } from \"./resolvers\";\n\n// build the schema as always\nconst schema = await buildSchema({\n  resolvers: [SampleResolver],\n  // register the 3rd party IOC container\n  container: Container,\n});\n```\n\nOur resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```typescript\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // constructor injection of a service\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```typescript\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```typescript\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```typescript\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `apollo-server` with the `context` creation method:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // schema comes from `buildSchema` as always\n  schema,\n  // provide unique context with `requestId` for each request\n  context: () => {\n    // generate the requestId (it also may come from `express-request-id` or other middleware)\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId); // get the scoped container\n    const context = { requestId, container }; // create fresh context object\n    container.set(\"context\", context); // place context or other data in container\n    return context;\n  },\n});\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `apollo-server` with plugins approach:\n\n```typescript\nimport { ApolloServer } from \"apollo-server\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // ... schema and context here\n  plugins: [\n    {\n      requestDidStart: () => ({\n        willSendResponse(requestContext) {\n          // remember to dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.context.requestId);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/directives.md",
    "content": "---\ntitle: Directives\nid: version-1.2.0-rc.1-directives\noriginal_id: directives\n---\n\n> 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.\n\nThough 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:\n\n```graphql\ntype Foo @auth(requires: USER) {\n  field: String!\n}\n\ntype Bar {\n  field: String! @auth(requires: USER)\n}\n```\n\nThat 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).\n\n**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator.\n\n## Usage\n\n### Declaring in schema\n\nBasically, we declare the usage of directives just like in SDL, with the `@` syntax:\n\n```typescript\n@Directive('@deprecated(reason: \"Use newField\")')\n```\n\nCurrently, 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.\n\nSo 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:\n\n```typescript\n@Directive(\"@auth(requires: USER)\")\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Directive(\"@auth(requires: USER)\")\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Directive(\"@auth(requires: ANY)\")\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Directive(\"@auth(requires: ADMIN)\")\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n> 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.\n\nAlso 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:\n\n```typescript\n@ObjectType()\nclass Foo {\n  @Directive(\"@lowercase\")\n  @Directive('@deprecated(reason: \"Use `newField`\")')\n  @Directive(\"@hasRole(role: Manager)\")\n  @Field()\n  bar: string;\n}\n```\n\n### Providing the implementation\n\nBesides declaring the usage of directives, you also have to register the runtime part of the used directives.\n\n> 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`.\n\nHere is an example using the [`graphql-tools`](https://github.com/apollographql/graphql-tools):\n\n```typescript\nimport { SchemaDirectiveVisitor } from \"graphql-tools\";\n\n// build the schema as always\nconst schema = buildSchemaSync({\n  resolvers: [SampleResolver],\n});\n\n// register the used directives implementations\nSchemaDirectiveVisitor.visitSchemaDirectives(schema, {\n  sample: SampleDirective,\n});\n```\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-1.2.0-rc.1-examples\noriginal_id: examples\n---\n\nOn 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.\n\nAll examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-subscriptions)\n- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typeorm-lazy-relations)\n- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/mikro-orm)\n- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typegoose)\n- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-federation)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-cache)\n- [Apollo Client state](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-client)\n- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/graphql-modules)\n\n_\\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-1.2.0-rc.1-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```typescript\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```typescript\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```typescript\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```typescript\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-1.2.0-rc.1-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`:\n\n```typescript\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`.\nIt also should have set `isAbstract: true` to prevent getting registered in the schema:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // `isAbstract` decorator option is mandatory to prevent registering in schema\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    // here we use the runtime argument\n    @Field(type => [TItemClass])\n    // and here the generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```typescript\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // we can freely add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```typescript\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // here is your custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```typescript\nexport default function PaginatedResponse<TItemsFieldValue>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType({ isAbstract: true })\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ...other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```typescript\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `isAbstract` option or the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```typescript\nexport default function PaginatedResponse<TItem>(TItemClass: ClassType<TItem>) {\n  // instead of `isAbstract`, we have to provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // the same fields as in the earlier code snippet\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```typescript\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // remember to provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // the same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-1.2.0-rc.1-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```typescript\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```typescript\n@ObjectType({ implements: [Person, Node] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```typescript\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```typescript\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```typescript\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // here we provide such object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```typescript\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // schema name of the type as a string\n    }\n    return Person; // or the object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-1.2.0-rc.1-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```typescript\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```typescript\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```typescript\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```typescript\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```typescript\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```typescript\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // write error to file log\n    fileLog.write(err, context, info);\n\n    // hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```typescript\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```typescript\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md).\n\n```typescript\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/performance.md",
    "content": "---\ntitle: Performance\nid: version-1.2.0-rc.1-performance\noriginal_id: performance\n---\n\n**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.\n\nWhile this enable easy and convenient development, it's sometimes a tradeoff in a performance.\n\n## Benchmarks\n\nTo 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).\n\nThe most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower.\n\n|                      | 25 000 array items | Deeply nested object |\n| -------------------- | :----------------: | :------------------: |\n| Standard TypeGraphQL |     1253.28 ms     |       45.57 μs       |\n| `graphql-js`         |     265.52 ms      |       24.22 μs       |\n\nIn 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.\n\n## Optimizations\n\nPromises 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`.\n\n| `graphql-js`    | 25 000 array items |\n| --------------- | :----------------: |\n| sync resolvers  |     265.52 ms      |\n| async resolvers |     512.61 ms      |\n\nTypeGraphQL 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.\n\nAlso, 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).\n\nThe 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!\n\n## Further performance tweaks\n\nWhen 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.:\n\n```typescript\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField: string;\n\n  @Field({ simple: true })\n  publicFrequentlyQueriedField: SomeType;\n}\n```\n\nMoreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.:\n\n```typescript\n@ObjectType({ simpleResolvers: true })\nclass Post {\n  @Field()\n  title: string;\n\n  @Field()\n  createdAt: Date;\n\n  @Field()\n  isPublished: boolean;\n}\n```\n\nThis 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):\n\n|                                                                               | 25 000 array items |\n| ----------------------------------------------------------------------------- | :----------------: |\n| `graphql-js`                                                                  |     265.52 ms      |\n| Standard TypeGraphQL                                                          |     310.36 ms      |\n| TypeGraphQL with a global middleware                                          |     1253.28 ms     |\n| **TypeGraphQL with \"simpleResolvers\" applied <br> (and a global middleware)** |   **299.61 ms**    |\n\n> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature.\n\nBy 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.\n\nThat'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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-1.2.0-rc.1-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```typescript\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // fake async in this example\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```typescript\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](validation.md).\n\nWe 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.\n\n```typescript\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // sample implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```typescript\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```typescript\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```typescript\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```typescript\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // sample implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```typescript\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```typescript\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```typescript\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    private userRepository: Repository<User>, // dependency injection\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-1.2.0-rc.1-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // or topics array\n    topics: ({ args, payload, context }) => args.topic // or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: (root, args, context, info) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```typescript\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // here we can trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```typescript\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [__dirname + \"/**/*.resolver.ts\"],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nFortunately, 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).\nThe `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:\n\n```typescript\n// Create GraphQL server\nconst server = new ApolloServer({\n  schema,\n  subscriptions: {\n    path: \"/subscriptions\",\n    // other options and hooks, like `onConnect`\n  },\n});\n```\n\nAnd it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server.\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-subscriptions).\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/unions.md",
    "content": "---\ntitle: Unions\nid: version-1.2.0-rc.1-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```typescript\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```typescript\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```typescript\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // the name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```typescript\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```typescript\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // our implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // we can return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # for sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-1.2.0-rc.1/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-1.2.0-rc.1-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validators) section.\n\n## `class-validator`\n\n### How to use\n\nFirst we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```typescript\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```typescript\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```typescript\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // you can be 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```typescript\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```typescript\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (F:\\\\#Projekty\\\\type-graphql\\\\src\\\\resolvers\\\\validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (F:\\\\#Projekty\\\\type-graphql\\\\node_modules\\\\tslib\\\\tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Example\n\nTo 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).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`.\nIt receives two parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`).\n\nThe `validate` function can be async and should return nothing (`void`) when validation passes or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validate` function for TypeGraphQL.\n\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...other options\n  validate: argValue => {\n    // call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Example\n\nTo 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-beta.3-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/bootstrap.md",
    "content": "---\ntitle: Bootstrapping\nid: version-2.0.0-beta.3-bootstrap\noriginal_id: bootstrap\n---\n\nAfter 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.\n\n## Create Executable Schema\n\nTo create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.\nIt takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.\n\nIn the configuration object we must provide a `resolvers` property, which is supposed to be an array of resolver classes:\n\n```ts\nimport { FirstResolver, SecondResolver } from \"./resolvers\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nBe aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema.\n\nSo 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`:\n\n```ts\nimport { FirstResolver, SecondResolver } from \"../app/src/resolvers\";\nimport { FirstObject } from \"../app/src/types\";\n// ...\nconst schema = await buildSchema({\n  resolvers: [FirstResolver, SecondResolver],\n  // Provide all the types that are missing in schema\n  orphanedTypes: [FirstObject],\n});\n```\n\nIn 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<T>` constraints:\n\n```ts\n// resolvers.ts\nexport const resolvers = [FirstResolver, SecondResolver] as const;\n\n// schema.ts\nimport { resolvers } from \"./resolvers\";\n\nconst schema = await buildSchema({ resolvers });\n```\n\nThere are also other options related to advanced features like [authorization](./authorization.md) or [validation](./validation.md) - you can read about them in docs.\n\nTo make `await` work, we need to declare it as an async function. Example of `main.ts` file:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n\nasync function bootstrap() {\n  const schema = await buildSchema({\n    resolvers: [\n      // ... Resolvers classes\n    ],\n  });\n\n  // ...\n}\n\nbootstrap(); // Actually run the async function\n```\n\n## Create an HTTP GraphQL endpoint\n\nIn 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).\n\nBelow is an example using [`@apollo/server`](https://github.com/apollographql/apollo-server):\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\n\nconst PORT = process.env.PORT || 4000;\n\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({ schema });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n\nbootstrap();\n```\n\nRemember to install the `@apollo/server` package from npm - it's not bundled with TypeGraphQL.\n\nOf course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉\n\n## Create typeDefs and resolvers map\n\nTypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.\n\nIt 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):\n\n```ts\nimport { makeExecutableSchema } from \"@graphql-tools/schema\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n```\n\nOr even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):\n\n```ts\nimport { withClientState } from \"apollo-link-state\";\n\nconst { typeDefs, resolvers } = await buildTypeDefsAndResolvers({\n  resolvers: [FirstResolver, SecondResolver],\n});\n\nconst stateLink = withClientState({\n  // ... Other options like `cache`\n  typeDefs,\n  resolvers,\n});\n\n// ... Rest of `ApolloClient` initialization code\n```\n\nThere's also a `sync` version of it - `buildTypeDefsAndResolversSync`:\n\n```ts\nconst { typeDefs, resolvers } = buildTypeDefsAndResolversSync({\n  resolvers: [FirstResolver, SecondResolver],\n});\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-2.0.0-beta.3-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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:\n\n```js\nmodule.exports = {\n  // ... Rest of Webpack configuration\n  plugins: [\n    // ... Other existing plugins\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/dist/browser-shim.js\");\n    }),\n  ];\n}\n```\n\nIn 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.\n\nHowever, 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:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"./node_modules/type-graphql/dist/browser-shim.ts\"]\n    }\n  }\n}\n```\n\nThanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-beta.3-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-beta.3-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-beta.3-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou 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).\n\nFor 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).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/directives.md",
    "content": "---\ntitle: Directives\nid: version-2.0.0-beta.3-directives\noriginal_id: directives\n---\n\n> 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.\n\nThough 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:\n\n```graphql\ntype Foo @auth(requires: USER) {\n  field: String!\n}\n\ntype Bar {\n  field: String! @auth(requires: USER)\n}\n```\n\nThat 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).\n\n**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator.\n\n## Usage\n\n### Declaring in schema\n\nBasically, we declare the usage of directives just like in SDL, with the `@` syntax:\n\n```ts\n@Directive('@deprecated(reason: \"Use newField\")')\n```\n\nCurrently, 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.\n\nSo 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:\n\n```ts\n@Directive(\"@auth(requires: USER)\")\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Directive(\"@auth(requires: USER)\")\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Directive(\"@auth(requires: ANY)\")\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Directive(\"@auth(requires: ADMIN)\")\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n> 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.\n\nAlso 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:\n\n```ts\n@ObjectType()\nclass Foo {\n  @Directive(\"@lowercase\")\n  @Directive('@deprecated(reason: \"Use `newField`\")')\n  @Directive(\"@hasRole(role: Manager)\")\n  @Field()\n  bar: string;\n}\n```\n\n### Providing the implementation\n\nBesides declaring the usage of directives, you also have to register the runtime part of the used directives.\n\n> 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`.\n\nIf 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:\n\n```ts\n// Build TypeGraphQL executable schema\nconst tempSchema = await buildSchema({\n  resolvers: [SampleResolver],\n  // Register the directives definitions\n  directives: [myDirective],\n});\n```\n\nThen you need to apply the schema transformer for your directive, that implements the desired logic of your directive:\n\n```ts\n// Transform and obtain the final schema\nconst schema = myDirectiveTransformer(tempSchema);\n```\n\nIf 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.\n\nHere is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools):\n\n```ts\nimport { mergeSchemas } from \"@graphql-tools/schema\";\nimport { renameDirective } from \"fake-rename-directive-package\";\n\n// Build TypeGraphQL executable schema\nconst schemaSimple = await buildSchema({\n  resolvers: [SampleResolver],\n});\n\n// Merge schema with sample directive type definitions\nconst schemaMerged = mergeSchemas({\n  schemas: [schemaSimple],\n  // Register the directives definitions\n  typeDefs: [renameDirective.typeDefs],\n});\n\n// Transform and obtain the final schema\nconst schema = renameDirective.transformer(schemaMerged);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\nid: version-2.0.0-beta.3-emit-schema\noriginal_id: emit-schema\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // Automatically create `schema.graphql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // Or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.graphql\"),\n  // Or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.graphql\",\n    sortedSchema: false, // By default the printed schema is sorted alphabetically\n  },\n});\n```\n\nThe 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.\n\n```ts\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.graphql\", schema);\n});\n```\n\n### Emit schema with custom directives\n\nCurrently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`.\n\nIf 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.\n\nBelow there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils):\n\n```ts\nimport { GraphQLSchema, lexicographicSortSchema } from \"graphql\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport { outputFile } from \"type-graphql/dist/helpers/filesystem\";\n\nexport async function emitSchemaDefinitionWithDirectivesFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n): Promise<void> {\n  const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema));\n  await outputFile(schemaFilePath, schemaFileContent);\n}\n```\n\nThe usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`:\n\n```ts\nconst schema = await buildSchema(/*...*/);\n\nawait emitSchemaDefinitionWithDirectivesFile(\"/path/to/folder/schema.graphql\", schema);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/enums.md",
    "content": "---\ntitle: Enums\nid: version-2.0.0-beta.3-enums\noriginal_id: enums\n---\n\nNowadays 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.\n\nGraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema.\n\n## Creating enum\n\nLet'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:\n\n```ts\n// Implicit value 0, 1, 2, 3\nenum Direction {\n  UP,\n  DOWN,\n  LEFT,\n  RIGHT,\n}\n\n// Or explicit values\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n\nTo 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:\n\n```ts\nimport { registerEnumType } from \"type-graphql\";\n\nregisterEnumType(Direction, {\n  name: \"Direction\", // Mandatory\n  description: \"The basic directions\", // Optional\n});\n```\n\nIn 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.:\n\n```ts\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n  SIDEWAYS = \"SIDEWAYS\",\n}\n\nregisterEnumType(Direction, {\n  name: \"Direction\",\n  description: \"The basic directions\",\n  valuesConfig: {\n    SIDEWAYS: {\n      deprecationReason: \"Replaced with Left or Right\",\n    },\n    RIGHT: {\n      description: \"The other left\",\n    },\n  },\n});\n```\n\nThis way, the additional info will be emitted in the GraphQL schema:\n\n```graphql\nenum Direction {\n  UP\n  DOWN\n  LEFT\n  \"\"\"\n  The other left\n  \"\"\"\n  RIGHT\n  SIDEWAYS @deprecated(reason: \"Replaced with Left or Right\")\n}\n```\n\n## Using enum\n\nThe 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:\n\n```ts\n@InputType()\nclass JourneyInput {\n  @Field(type => Direction) // Mandatory\n  direction: Direction;\n}\n```\n\nWithout this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for.\n\nWith all that in place, we can use our enum directly in our code 😉\n\n```ts\n@Resolver()\nclass SpriteResolver {\n  private sprite = getMarioSprite();\n\n  @Mutation()\n  move(@Arg(\"direction\", type => Direction) direction: Direction): boolean {\n    switch (direction) {\n      case Direction.Up:\n        this.sprite.position.y++;\n        break;\n      case Direction.Down:\n        this.sprite.position.y--;\n        break;\n      case Direction.Left:\n        this.sprite.position.x--;\n        break;\n      case Direction.Right:\n        this.sprite.position.x++;\n        break;\n      default:\n        // Never reached\n        return false;\n    }\n\n    return true;\n  }\n}\n```\n\n## Interoperability\n\nEnums 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`).\n\nSo 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.:\n\n```ts\nenum Direction {\n  UP = \"UP\",\n  DOWN = \"DOWN\",\n  LEFT = \"LEFT\",\n  RIGHT = \"RIGHT\",\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/esm.md",
    "content": "---\ntitle: ECMAScript Modules\nid: version-2.0.0-beta.3-esm\noriginal_id: esm\n---\n\nSince `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules.\n\nThanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle.\n\n## TypeScript configuration\n\nIt's important to properly configure the project, so that it uses ESM correctly:\n\n- the `module` options should be set to `ES2020/ES2022/ESNext`\n- for the NodeJS apps, we should set `moduleResolution` to `\"node16\"`\n\nAll in all, the `tsconfig.json` file should looks like this:\n\n```json title=\"tsconfig.json\"\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"es2020\",\n    \"moduleResolution\": \"node16\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n\n## Package.json configuration\n\nIt is also important to set `type` option to `\"module\"` in your `package.json` file:\n\n```json title=\"package.json\"\n{\n  \"type\": \"module\"\n}\n```\n\n## Imports\n\nApart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.:\n\n```ts\nimport { MyResolver } from \"./resolvers/MyResolver.js\";\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-beta.3-examples\noriginal_id: examples\n---\n\nOn 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.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typegoose)\n- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/apollo-federation)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-beta.3-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/faq.md",
    "content": "---\ntitle: Frequently Asked Questions\nid: version-2.0.0-beta.3-faq\noriginal_id: faq\n---\n\n## Resolvers\n\n### Should I implement a field resolver as an object type getter, a method or a resolver class method?\n\nThis depends on various factors:\n\n- if the resolver only needs access to the root/object value - use a getter\n- if the field has arguments\n  - and must perform side effects e.g. a database call - use a resolver class method and leverage the dependency injection mechanism\n  - otherwise, use object type methods (pure functions, calculations based on object values and arguments)\n- if the business logic must be separated from the type definition - use a resolver class method\n\n### Are there any global error handlers to catch errors from resolvers or services?\n\nUse middleware for this purpose - just wrap `await next()` in a try-catch block then register it as the first global middleware.\n\n### Why did I receive this error? `GraphQLError: Expected value of type \"MyType\" but got: [object Object]`\n\nThis error occurs when the resolver (query, mutation, field) type is an interface/union and a plain object is returned from it.\nIn this case, what should be returned is an instance of the selected object type class in the resolver.\nOtherwise, `graphql-js` will not be able to correctly detect the underlying GraphQL type.\n\n## Bootstrapping\n\n### How do I fix this error? `Cannot use GraphQLSchema \"[object Object]\" from another module or realm`\n\nThis error occurs mostly when there are more than one version of the `graphql-js` module in the project.\nIn 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`.\nWe can print the dependency tree by running `npm ls graphql` (or the yarn equivalent) to find the faulty dependencies.\nThen we should update or downgrade them until they all match the semver on `graphql`, e.g. `^14.0.0`.\nDependencies 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).\n\nThe 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'`.\nIn this case we repeat the same checks but for the `@types/graphql` module in our dependencies.\n\n## Types\n\n### Is `@InputType()` different from `@ArgsType()`?\n\nOf course!\n`@InputType` will generate a real `GraphQLInputType` type and should be used when we need a nested object in the args:\n\n```graphql\nupdateItem(data: UpdateItemInput!): Item!\n```\n\n`@ArgsType` is virtual and it will be flattened in schema:\n\n```graphql\nupdateItem(id: Int!, userId: Int!): Item!\n```\n\n### When should I use the `() => [ItemType]` syntax?\n\nWe should use the `[ItemType]` syntax any time the field type or the return type is an array from a query or mutation.\n\nEven 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.\n\n### How can I define a tuple?\n\nUnfortunately, [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.\n\nInstead, you have to create a transient object (or input) type that fits your data, e.g.:\n\n```graphql\ntype DataPoint {\n  x: Int\n  y: Float\n}\n```\n\nand then use it in the list type as your GraphQL type:\n\n```graphql\ndata: [DataPoint]\n```\n\n### Situations frequently arise where InputType and ObjectType have exactly the same shape. How can I share the definitions?\n\nIn 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.\nHowever, 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:\n\n```ts\n@ObjectType() // Name inferred as 'Person' from class name\n@InputType(\"PersonInput\")\nexport class Person {}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-beta.3-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/getting-started.md",
    "content": "---\ntitle: Getting started\nid: version-2.0.0-beta.3-getting-started\noriginal_id: getting-started\n---\n\n> Make sure you've completed all the steps described in the [installation instructions](./installation.md).\n\nTo explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes.\n\nLet's start with the `Recipe` type, which is the foundation of our API.\n\n## Types\n\nOur goal is to get the equivalent of this type described in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\n```\n\nSo we create the `Recipe` class with all its properties and types:\n\n```ts\nclass Recipe {\n  id: string;\n  title: string;\n  description?: string;\n  creationDate: Date;\n  ingredients: string[];\n}\n```\n\nThen we decorate the class and its properties with decorators:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n\n  @Field()\n  creationDate: Date;\n\n  @Field(type => [String])\n  ingredients: string[];\n}\n```\n\nThe detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](./types-and-fields.md).\n\n## Resolvers\n\nAfter 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:\n\n```ts\n@Resolver(Recipe)\nclass RecipeResolver {\n  constructor(private recipeService: RecipeService) {}\n\n  @Query(returns => Recipe)\n  async recipe(@Arg(\"id\") id: string) {\n    const recipe = await this.recipeService.findById(id);\n    if (recipe === undefined) {\n      throw new RecipeNotFoundError(id);\n    }\n    return recipe;\n  }\n\n  @Query(returns => [Recipe])\n  recipes(@Args() { skip, take }: RecipesArgs) {\n    return this.recipeService.findAll({ skip, take });\n  }\n\n  @Mutation(returns => Recipe)\n  @Authorized()\n  addRecipe(\n    @Arg(\"newRecipeData\") newRecipeData: NewRecipeInput,\n    @Ctx(\"user\") user: User,\n  ): Promise<Recipe> {\n    return this.recipeService.addNew({ data: newRecipeData, user });\n  }\n\n  @Mutation(returns => Boolean)\n  @Authorized(Roles.Admin)\n  async removeRecipe(@Arg(\"id\") id: string) {\n    try {\n      await this.recipeService.removeById(id);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n```\n\nWe use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements.\nThe detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](./resolvers.md).\n\n## Inputs and Arguments\n\nOk, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes:\n\n```ts\n@InputType()\nclass NewRecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n\n  @Field(type => [String])\n  @ArrayMaxSize(30)\n  ingredients: string[];\n}\n\n@ArgsType()\nclass RecipesArgs {\n  @Field(type => Int)\n  @Min(0)\n  skip: number = 0;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take: number = 25;\n}\n```\n\n`@Length`, `@Min` and `@ArrayMaxSize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL.\n\n## Building schema\n\nThe last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n});\n\n// ... Server\n```\n\nEt voilà! Now we have fully functional GraphQL schema!\nIf we print it, this is how it would look:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  description: String\n  creationDate: Date!\n  ingredients: [String!]!\n}\ninput NewRecipeInput {\n  title: String!\n  description: String\n  ingredients: [String!]!\n}\ntype Query {\n  recipe(id: ID!): Recipe\n  recipes(skip: Int = 0, take: Int = 25): [Recipe!]!\n}\ntype Mutation {\n  addRecipe(newRecipeData: NewRecipeInput!): Recipe!\n  removeRecipe(id: ID!): Boolean!\n}\n```\n\n## Want more?\n\nThat 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.\n\nA 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.\n\nFor more complicated cases, go to the [Examples section](./examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-beta.3-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/installation.md",
    "content": "---\ntitle: Installation\nid: version-2.0.0-beta.3-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> #### Prerequisites\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, 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:\n\n```sh\nnpm install graphql graphql-scalars type-graphql\n```\n\nAlso, the `reflect-metadata` shim is required to make the type reflection work:\n\n```sh\nnpm install reflect-metadata\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```ts\nimport \"reflect-metadata\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`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:\n\n```js\n{\n  \"target\": \"es2021\" // Or newer if Node.js version supports it\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"commonjs\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-beta.3-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar_label: What & Why\nid: version-2.0.0-beta.3-introduction\noriginal_id: introduction\n---\n\nWe 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.\n\n## What?\n\n**TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic.\nExample object type:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nIt also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL APIs quickly & easily!\n\n## Why?\n\nAs mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain.\nWhy? Let's take a look at the steps we usually have to take.\n\nFirst, 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.:\n\n```ts\nexport const getRecipesResolver: GraphQLFieldResolver<void, Context, GetRecipesArgs> = async (\n  _,\n  args,\n  ctx,\n) => {\n  // Common tasks repeatable for almost every resolver\n  const auth = Container.get(AuthService);\n  if (!auth.check(ctx.user)) {\n    throw new NotAuthorizedError();\n  }\n  await joi.validate(getRecipesSchema, args);\n  const repository = TypeORM.getRepository(Recipe);\n\n  // Business logic, e.g.:\n  return repository.find({ skip: args.offset, take: args.limit });\n};\n```\n\nThe 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.\n\n**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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-beta.3-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/nestjs.md",
    "content": "---\ntitle: NestJS Integration\nsidebar_label: NestJS\nid: version-2.0.0-beta.3-nestjs\noriginal_id: nestjs\n---\n\nTypeGraphQL provides some basic integration with NestJS by the [`typegraphql-nestjs` package](https://www.npmjs.com/package/typegraphql-nestjs).\n\nIt allows to use TypeGraphQL features while integrating with NestJS modules system and its dependency injector.\n\n## Overview\n\nThe usage is similar to the official `@nestjs/graphql` package.\nFirst you need to register your resolver classes in `providers` of the `@Module` :\n\n```ts\n@Module({\n  providers: [RecipeResolver, RecipeService],\n})\nexport default class RecipeModule {}\n```\n\nThen you need to register the TypeGraphQL module in your root module - you can pass there all standard `buildSchema` options:\n\n```ts\n@Module({\n  imports: [\n    TypeGraphQLModule.forRoot({\n      emitSchemaFile: true,\n      authChecker,\n      context: ({ req }) => ({ currentUser: req.user }),\n    }),\n    RecipeModule,\n  ],\n})\nexport default class AppModule {}\n```\n\nAnd your `AppModule` is ready to use like with a standard NestJS approach.\n\n### Caveats\n\nFor now, this basic integration doesn't support other NestJS features like guards, interceptors, filters and pipes.\nTo achieve the same goals, you can use standard TypeGraphQL equivalents - middlewares, custom decorators, built-in authorization and validation.\n\n## Documentation and examples\n\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/performance.md",
    "content": "---\ntitle: Performance\nid: version-2.0.0-beta.3-performance\noriginal_id: performance\n---\n\n**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.\n\nWhile this enable easy and convenient development, it's sometimes a tradeoff in a performance.\n\n## Benchmarks\n\nTo 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).\n\nThe most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower.\n\n|                      | 25 000 array items | Deeply nested object |\n| -------------------- | :----------------: | :------------------: |\n| Standard TypeGraphQL |     1253.28 ms     |       45.57 μs       |\n| `graphql-js`         |     265.52 ms      |       24.22 μs       |\n\nIn 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.\n\n## Optimizations\n\nPromises 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`.\n\n| `graphql-js`    | 25 000 array items |\n| --------------- | :----------------: |\n| sync resolvers  |     265.52 ms      |\n| async resolvers |     512.61 ms      |\n\nTypeGraphQL 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.\n\nAlso, 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).\n\nThe 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!\n\n## Further performance tweaks\n\nWhen 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.:\n\n```ts\n@ObjectType()\nclass SampleObject {\n  @Field()\n  sampleField: string;\n\n  @Field({ simple: true })\n  publicFrequentlyQueriedField: SomeType;\n}\n```\n\nMoreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.:\n\n```ts\n@ObjectType({ simpleResolvers: true })\nclass Post {\n  @Field()\n  title: string;\n\n  @Field()\n  createdAt: Date;\n\n  @Field()\n  isPublished: boolean;\n}\n```\n\nThis 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):\n\n|                                                                          | 25 000 array items |\n| ------------------------------------------------------------------------ | :----------------: |\n| `graphql-js`                                                             |     265.52 ms      |\n| Standard TypeGraphQL                                                     |     310.36 ms      |\n| TypeGraphQL with a global middleware                                     |     1253.28 ms     |\n| **TypeGraphQL with \"simpleResolvers\" applied (and a global middleware)** |   **299.61 ms**    |\n\n> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature.\n\nBy 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.\n\nThat'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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/prisma.md",
    "content": "---\ntitle: Prisma Integration\nsidebar_label: Prisma\nid: version-2.0.0-beta.3-prisma\noriginal_id: prisma\n---\n\nTypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma).\n\nIt 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.\n\n## Overview\n\nTo make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file:\n\n```sh\ngenerator typegraphql {\n  provider = \"typegraphql-prisma\"\n}\n```\n\nThen, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema:\n\n```ts\nimport { resolvers } from \"@generated/type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  validate: false,\n});\n```\n\nSo we will be able to execute a complex query, that talks with the real database, in just a few minutes!\n\n```graphql\nquery GetSomeUsers {\n  users(where: { email: { contains: \"prisma\" } }, orderBy: { name: desc }) {\n    id\n    name\n    email\n    posts(take: 10, orderBy: { updatedAt: desc }) {\n      published\n      title\n      content\n    }\n  }\n}\n```\n\n## Documentation and examples\n\nTo 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).\n\nThere also can be found the links to some examples and more detailed info about the installation and the configuration.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-beta.3-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/scalars.md",
    "content": "---\ntitle: Scalars\nid: version-2.0.0-beta.3-scalars\noriginal_id: scalars\n---\n\n## Aliases\n\nTypeGraphQL provides aliases for 3 basic scalars:\n\n- Int --> GraphQLInt;\n- Float --> GraphQLFloat;\n- ID --> GraphQLID;\n\nThis shorthand allows you to save keystrokes when declaring field types:\n\n```ts\n// Import the aliases\nimport { ID, Float, Int } from \"type-graphql\";\n\n@ObjectType()\nclass MysteryObject {\n  @Field(type => ID)\n  readonly id: string;\n\n  @Field(type => Int)\n  notificationsCount: number;\n\n  @Field(type => Float)\n  probability: number;\n}\n```\n\nIn the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically.\n\nOther scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically:\n\n```ts\n@ObjectType()\nclass User {\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nHowever in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then:\n\n```ts\n@ObjectType()\nclass SampleObject {\n  @Field(type => String, { nullable: true })\n  // TS reflected type is `Object` :(\n  get optionalInfo(): string | undefined {\n    if (Math.random() > 0.5) {\n      return \"Gotcha!\";\n    }\n  }\n}\n```\n\n## Custom Scalars\n\nTypeGraphQL also supports custom scalar types!\n\nFirst 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:\n\n```ts\nimport { GraphQLScalarType, Kind } from \"graphql\";\nimport { ObjectId } from \"mongodb\";\n\nexport const ObjectIdScalar = new GraphQLScalarType({\n  name: \"ObjectId\",\n  description: \"Mongo object id scalar type\",\n  serialize(value: unknown): string {\n    // Check type of value\n    if (!(value instanceof ObjectId)) {\n      throw new Error(\"ObjectIdScalar can only serialize ObjectId values\");\n    }\n    return value.toHexString(); // Value sent to client\n  },\n  parseValue(value: unknown): ObjectId {\n    // Check type of value\n    if (typeof value !== \"string\") {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(value); // Value from client input variables\n  },\n  parseLiteral(ast): ObjectId {\n    // Check type of value\n    if (ast.kind !== Kind.STRING) {\n      throw new Error(\"ObjectIdScalar can only parse string values\");\n    }\n    return new ObjectId(ast.value); // Value from client query\n  },\n});\n```\n\nThen we can just use it in our field decorators:\n\n```ts\n// Import earlier created const\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\n\n@ObjectType()\nclass User {\n  @Field(type => ObjectIdScalar) // Explicitly use it\n  readonly id: ObjectId;\n\n  @Field()\n  name: string;\n\n  @Field()\n  isOld: boolean;\n}\n```\n\nOptionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!):\n\n```ts\n@ObjectType()\nclass User {\n  @Field() // Magic goes here - no type annotation for custom scalar\n  readonly id: ObjectId;\n}\n```\n\nAll we need to do is register the association map in the `buildSchema` options:\n\n```ts\nimport { ObjectId } from \"mongodb\";\nimport { ObjectIdScalar } from \"../my-scalars/ObjectId\";\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }],\n});\n```\n\nHowever, 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.\n\n## Date Scalars\n\nTypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar:\n\n- ISO-formatted string: `\"2023-05-19T21:04:39.573Z\"`\n- timestamp-based number: `1518037458374`\n\nThey are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp` but comes from `graphql-scalars` npm package.\n\nBy default, TypeGraphQL uses the ISO date format, however we can change it to timestamp format using the mentioned above `scalarsMap` option of `buildSchema` configuration:\n\n```ts\nimport { buildSchema, GraphQLTimestamp } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],\n});\n```\n\nThere's no need then to explicitly declare the field type:\n\n```ts\n@ObjectType()\nclass User {\n  @Field()\n  registrationDate: Date;\n}\n```\n\nWe can of course use any other `Date` scalar from `graphql-scalars` or any other npm package.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-beta.3-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, payload, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll 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:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: (root, args, context, info) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nWe use the `@PubSub()` decorator to inject the `pubsub` into our method params.\nThere we can trigger the topics and send the payload to all topic subscribers.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    await pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nFor easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic.\nThis is done by using the `@PubSub(\"TOPIC_NAME\")` decorator and the `Publisher<TPayload>` type:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(\n    @Arg(\"comment\") input: CommentInput,\n    @PubSub(\"NOTIFICATIONS\") publish: Publisher<NotificationPayload>,\n  ) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    await publish({ message: input.content });\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Using a custom PubSub system\n\nBy default, TypeGraphQL uses a simple `PubSub` system from `graphql-subscriptions` which is based on EventEmitter.\nThis solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app.\n\nFor 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.\n\nAll we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options:\n\n```ts\nconst myRedisPubSub = getConfiguredRedisPubSub();\n\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  pubSub: myRedisPubSub,\n});\n```\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-subscriptions).\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/types-and-fields.md",
    "content": "---\ntitle: Types and Fields\nid: version-2.0.0-beta.3-types-and-fields\noriginal_id: types-and-fields\n---\n\nThe 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.\n\nLet's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data:\n\n```ts\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating?: number;\n}\n```\n\nThe 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`:\n\n```ts\n@ObjectType()\nclass Recipe {\n  id: string;\n  title: string;\n  ratings: Rate[];\n  averageRating: number;\n}\n```\n\nThen we declare which class properties should be mapped to the GraphQL fields.\nTo do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  id: string;\n\n  @Field()\n  title: string;\n\n  @Field()\n  ratings: Rate[];\n\n  @Field()\n  averageRating: number;\n}\n```\n\nFor 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])`.\nFor 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.\n\nWhy 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.\n\nBy 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).\n\nSo 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.\n\nIn 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\"`.\n\nFor 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]]!`\n\nIn the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes.\n\nSo after these changes our example class would look like this:\n\n```ts\n@ObjectType({ description: \"The recipe model\" })\nclass Recipe {\n  @Field(type => ID)\n  id: string;\n\n  @Field({ description: \"The title of the recipe\" })\n  title: string;\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field({ nullable: true })\n  averageRating?: number;\n}\n```\n\nWhich will result in generating the following part of the GraphQL schema in SDL:\n\n```graphql\ntype Recipe {\n  id: ID!\n  title: String!\n  ratings: [Rate!]!\n  averageRating: Float\n}\n```\n\nSimilarly, the `Rate` type class would look like this:\n\n```ts\n@ObjectType()\nclass Rate {\n  @Field(type => Int)\n  value: number;\n\n  @Field()\n  date: Date;\n\n  user: User;\n}\n```\n\nwhich results in this equivalent of the GraphQL SDL:\n\n```graphql\ntype Rate {\n  value: Int!\n  date: Date!\n}\n```\n\nAs 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.\n\nAlso 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.\n\nNote 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)).\n\nBe 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.\n\nIn some case we may want to expose our classes or properties under a different types or fields name.\nTo accomplish this, we can use the `name` parameter or `name` property of decorator's options, e.g.:\n\n```ts\n@ObjectType(\"ExternalTypeName\")\nclass InternalClassName {\n  @Field({ name: \"externalFieldName\" })\n  internalPropertyName: string;\n}\n```\n\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-beta.3-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.3/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-beta.3-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo 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).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`.\nIt receives two parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`).\n\nThe `validateFn` option can be an async function and should return nothing (`void`) when validation passes or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validate: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-beta.4-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/aws-lambda.md",
    "content": "---\ntitle: AWS Lambda integration\nid: version-2.0.0-beta.4-aws-lambda\noriginal_id: aws-lambda\n---\n\n## Using TypeGraphQL in AWS Lambda environment\n\nAWS Lambda environment is a bit different than a standard Node.js server deployment.\n\nHowever, 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.\n\nSo all we need to do is to assign the built schema to the local variable using the `??=` conditional assignment operator.\nWe can do the same thing for `ApolloServer`.\n\nBelow you you can find the full snippet for the AWS Lambda integration:\n\n```ts\nimport { APIGatewayProxyHandlerV2 } from \"aws-lambda\";\nimport { ApolloServer } from \"apollo-server-lambda\";\n\nlet cachedSchema: GraphQLSchema | null = null;\nlet cachedServer: ApolloServer | null = null;\n\nexport const handler: APIGatewayProxyHandlerV2 = async (event, context, callback) => {\n  // build TypeGraphQL executable schema only once, then read it from local \"cached\" variable\n  cachedSchema ??= await buildSchema({\n    resolvers: [RecipeResolver],\n  });\n\n  // create the GraphQL server only once\n  cachedServer ??= new ApolloServer({ schema: cachedSchema });\n\n  // make a handler for `aws-lambda`\n  return cachedServer.createHandler({})(event, context, callback);\n};\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-2.0.0-beta.4-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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:\n\n```js\nmodule.exports = {\n  // ... Rest of Webpack configuration\n  plugins: [\n    // ... Other existing plugins\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/shim\");\n    }),\n  ];\n}\n```\n\nIn 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.\n\nHowever, 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:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"./node_modules/type-graphql/build/typings/shim.ts\"]\n    }\n  }\n}\n```\n\nThanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-beta.4-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-beta.4-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-beta.4-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou 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).\n\nFor 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).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/directives.md",
    "content": "---\ntitle: Directives\nid: version-2.0.0-beta.4-directives\noriginal_id: directives\n---\n\n> 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.\n\nThough 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:\n\n```graphql\ntype Foo @auth(requires: USER) {\n  field: String!\n}\n\ntype Bar {\n  field: String! @auth(requires: USER)\n}\n```\n\nThat 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).\n\n**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator.\n\n## Usage\n\n### Declaring in schema\n\nBasically, we declare the usage of directives just like in SDL, with the `@` syntax:\n\n```ts\n@Directive('@deprecated(reason: \"Use newField\")')\n```\n\nCurrently, 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.\n\nSo 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:\n\n```ts\n@Directive(\"@auth(requires: USER)\")\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Directive(\"@auth(requires: USER)\")\n  @Field()\n  field: string;\n}\n\n@ArgsType()\nclass FooBarArgs {\n  @Directive('@deprecated(reason: \"Not used anymore\")')\n  @Field({ nullable: true })\n  baz?: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Directive(\"@auth(requires: ANY)\")\n  @Query()\n  foobar(@Args() { baz }: FooBarArgs): string {\n    return \"foobar\";\n  }\n\n  @Directive(\"@auth(requires: ADMIN)\")\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\nIn case of inline args using `@Arg` decorator, directives can be placed over the parameter of the class method:\n\n```ts\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Query()\n  foo(\n    @Directive('@deprecated(reason: \"Not used anymore\")')\n    @Arg(\"foobar\", { defaultValue: \"foobar\" })\n    foobar: string,\n  ) {\n    return \"foo\";\n  }\n\n  @FieldResolver()\n  bar(\n    @Directive('@deprecated(reason: \"Not used anymore\")')\n    @Arg(\"foobar\", { defaultValue: \"foobar\" })\n    foobar: string,\n  ) {\n    return \"bar\";\n  }\n}\n```\n\n> 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.\n\nAlso 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:\n\n```ts\n@ObjectType()\nclass Foo {\n  @Directive(\"@lowercase\")\n  @Directive('@deprecated(reason: \"Use `newField`\")')\n  @Directive(\"@hasRole(role: Manager)\")\n  @Field()\n  bar: string;\n}\n```\n\n### Providing the implementation\n\nBesides declaring the usage of directives, you also have to register the runtime part of the used directives.\n\n> 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`.\n\nIf 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:\n\n```ts\n// Build TypeGraphQL executable schema\nconst tempSchema = await buildSchema({\n  resolvers: [SampleResolver],\n  // Register the directives definitions\n  directives: [myDirective],\n});\n```\n\nThen you need to apply the schema transformer for your directive, that implements the desired logic of your directive:\n\n```ts\n// Transform and obtain the final schema\nconst schema = myDirectiveTransformer(tempSchema);\n```\n\nIf 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.\n\nHere is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools):\n\n```ts\nimport { mergeSchemas } from \"@graphql-tools/schema\";\nimport { renameDirective } from \"fake-rename-directive-package\";\n\n// Build TypeGraphQL executable schema\nconst schemaSimple = await buildSchema({\n  resolvers: [SampleResolver],\n});\n\n// Merge schema with sample directive type definitions\nconst schemaMerged = mergeSchemas({\n  schemas: [schemaSimple],\n  // Register the directives definitions\n  typeDefs: [renameDirective.typeDefs],\n});\n\n// Transform and obtain the final schema\nconst schema = renameDirective.transformer(schemaMerged);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\nid: version-2.0.0-beta.4-emit-schema\noriginal_id: emit-schema\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // Automatically create `schema.graphql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // Or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.graphql\"),\n  // Or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.graphql\",\n    sortedSchema: false, // By default the printed schema is sorted alphabetically\n  },\n});\n```\n\nThe 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.\n\n```ts\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.graphql\", schema);\n});\n```\n\n### Emit schema with custom directives\n\nCurrently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`.\n\nIf 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.\n\nBelow there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils):\n\n```ts\nimport { GraphQLSchema, lexicographicSortSchema } from \"graphql\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport fs from \"node:fs/promises\";\n\nexport async function emitSchemaDefinitionWithDirectivesFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n): Promise<void> {\n  const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema));\n  await fs.writeFile(schemaFilePath, schemaFileContent);\n}\n```\n\nThe usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`:\n\n```ts\nconst schema = await buildSchema(/*...*/);\n\nawait emitSchemaDefinitionWithDirectivesFile(\"/path/to/folder/schema.graphql\", schema);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/esm.md",
    "content": "---\ntitle: ECMAScript Modules\nid: version-2.0.0-beta.4-esm\noriginal_id: esm\n---\n\nSince `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules.\n\nThanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle.\n\n## TypeScript configuration\n\nIt's important to properly configure the project, so that it uses ESM correctly:\n\n- the `module` option should be set to `NodeNext`\n- the `moduleResolution` option should be set to `\"NodeNext\"`\n\nAll in all, the `tsconfig.json` file should looks like this:\n\n```json title=\"tsconfig.json\"\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n\n## Package.json configuration\n\nIt is also important to set `type` option to `\"module\"` in your `package.json` file:\n\n```json title=\"package.json\"\n{\n  \"type\": \"module\"\n}\n```\n\n## Imports\n\nApart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.:\n\n```ts\nimport { MyResolver } from \"./resolvers/MyResolver.js\";\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-beta.4-examples\noriginal_id: examples\n---\n\nOn 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.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-beta.4-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-beta.4-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-beta.4-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-beta.4-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-beta.4-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/migration-guide.md",
    "content": "---\ntitle: Migration Guide\nsidebar_label: v1.x -> v2.0\nid: version-2.0.0-beta.4-migration-guide\noriginal_id: migration-guide\n---\n\n> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release.\n>\n> 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.\n\n## Subscriptions\n\nThe new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature.\n\nIn previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system.\nHowever, it's become unmaintained in the last years and some alternatives has been developed in the meantime.\n\nSo 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.\n\nWe 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.\n\n### The `pubSub` option of `buildSchema`\n\nIt is now required to pass the `PubSub` instance as the config option of `buildSchema` function.\nPreviously, you could omit it and rely on the default one created by TypeGraphQL.\n\nThe 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.\n\nSimple example of the new API:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nBe aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\n### No `@PubSub` decorator\n\nThe consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance.\n\nHence, 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.\n\n### Renamed and removed types\n\nThere was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release.\n\nIf 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.\n\n- `ResolverFilterData` -> `SubscriptionHandlerData`\n- `ResolverTopicData` -> `SubscribeResolverData`\n\nAlso, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package.\n\n### Topic with Dynamic ID\n\nAs 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.\n\nYou can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-beta.4-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-beta.4-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: (root, args, context, info) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, 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.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> 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.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee 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.\n\n<!-- FIXME: restore when redis example is upgraded -->\n<!-- 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.4/examples/redis-subscriptions).\nHowever, 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. -->\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-beta.4-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.4/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-beta.4-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo 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).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-beta.6-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-beta.6-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-beta.6-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-beta.6-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou 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).\n\nFor 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).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-beta.6-examples\noriginal_id: examples\n---\n\nOn 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.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-beta.6-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-beta.6-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-beta.6-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-beta.6-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-beta.6-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-beta.6-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-beta.6-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: (root, args, context, info) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, 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.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> 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.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee 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.\n\n<!-- FIXME: restore when redis example is upgraded -->\n<!-- 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.6/examples/redis-subscriptions).\nHowever, 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. -->\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-beta.6-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-beta.6/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-beta.6-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo 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).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-rc.1-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## How to use\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nNext, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-rc.1-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-rc.1-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom 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.\n\n## Method decorators\n\nUsing [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.\n\nThey 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:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParamDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParamDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-rc.1-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou 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).\n\nFor 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).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-rc.1-examples\noriginal_id: examples\n---\n\nOn 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.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-rc.1-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-rc.1-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-rc.1-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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).\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/installation.md",
    "content": "---\ntitle: Installation\nid: version-2.0.0-rc.1-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> #### Prerequisites\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, 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:\n\n```sh\nnpm install graphql graphql-scalars type-graphql\n```\n\nAlso, the `Reflect.metadata()` shim is required to make the type reflection work:\n\n```sh\nnpm install reflect-metadata\n# or\nnpm install core-js\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```ts\nimport \"reflect-metadata\";\n// or\nimport \"core-js/features/reflect\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`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:\n\n```js\n{\n  \"target\": \"es2021\" // Or newer if Node.js version supports it\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"commonjs\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-rc.1-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-rc.1-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver.\n\nHence, 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:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/migration-guide.md",
    "content": "---\ntitle: Migration Guide\nsidebar_label: v1.x -> v2.0\nid: version-2.0.0-rc.1-migration-guide\noriginal_id: migration-guide\n---\n\n> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release.\n>\n> 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.\n\n## New `DateTimeISO` scalar name in schema\n\nOne 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.\n\nThis 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.\n\nFirst, you need to create an alias for the `GraphQLDateTimeISO` scalar:\n\n```ts\nimport { GraphQLDateTimeISO } from \"graphql-scalars\";\nimport { GraphQLScalarType } from \"graphql\";\n\nconst AliasedGraphQLDateTimeISO = new GraphQLScalarType({\n  ...GraphQLDateTimeISO.toConfig(),\n  name: \"DateTime\", // use old name\n});\n```\n\nAnd then register the scalars mapping in the schema you build, in order to overwrite the default date scalar:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n\nconst schema = await buildSchema({\n  resolvers,\n  scalarsMap: [{ type: Date, scalar: AliasedGraphQLDateTimeISO }],\n});\n```\n\nAn 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.\n\n## Subscriptions\n\nThe new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature.\n\nIn previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system.\nHowever, it's become unmaintained in the last years and some alternatives has been developed in the meantime.\n\nSo 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.\n\nWe 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.\n\n### The `pubSub` option of `buildSchema`\n\nIt is now required to pass the `PubSub` instance as the config option of `buildSchema` function.\nPreviously, you could omit it and rely on the default one created by TypeGraphQL.\n\nThe 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.\n\nSimple example of the new API:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nBe aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\n### No `@PubSub` decorator\n\nThe consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance.\n\nHence, 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.\n\n### Renamed and removed types\n\nThere was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release.\n\nIf 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.\n\n- `ResolverFilterData` -> `SubscriptionHandlerData`\n- `ResolverTopicData` -> `SubscribeResolverData`\n\nAlso, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package.\n\n### Topic with Dynamic ID\n\nAs 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.\n\nYou can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-rc.1-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-rc.1-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ root, args, context, info }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, 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.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> 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.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee 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.\n\nFor 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).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-rc.1-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.1/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-rc.1-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo 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).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo 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).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-rc.2-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## Declaration\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nHowever, declaring `@Authorized()` on all the resolver's class methods would be not only a tedious task but also an error-prone one, as it's easy to forget to put it on some newly added method, etc.\nHence, TypeGraphQL support declaring `@Authorized()` or the resolver class level. This way you can declare it once per resolver's class but you can still overwrite the defaults and narrows the authorization rules:\n\n```ts\n@Authorized()\n@Resolver()\nclass MyResolver {\n  // this will inherit the auth guard defined on the class level\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  // this one overwrites the resolver's one\n  // and registers roles required for this mutation\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\n## Runtime checks\n\nHaving all the metadata for authorization set, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/azure-functions.md",
    "content": "---\ntitle: Azure Functions Integration\nid: version-2.0.0-rc.2-azure-functions\noriginal_id: azure-functions\n---\n\n## Using TypeGraphQL in Microsoft Azure Functions\n\nIntegrating TypeGraphQL with Azure Functions involves the following key steps:\n\n1. Generate GraphQL schema based on your resolvers\n2. Notify Apollo Server about your schema\n\nBelow is how you can implement the azure function entry point (with explanations in-line):\n\n```ts\n// index.ts\n\nimport \"reflect-metadata\";\nimport path from \"path\";\nimport { ApolloServer } from \"@apollo/server\";\nimport { startServerAndCreateHandler } from \"@as-integrations/azure-functions\";\nimport { buildSchemaSync } from \"type-graphql\";\nimport { Container } from \"typedi\";\nimport { GraphQLFormattedError } from \"graphql\";\nimport { UserResolver } from \"YOUR_IMPORT_PATH\"; // TypeGraphQL Resolver\nimport { AccountResolver } from \"YOUR_IMPORT_PATH\"; // TypeGraphQL Resolver\n\n// Bundle resolvers to build the schema\nconst schema = buildSchemaSync({\n  // Include resolvers you'd like to expose to the API\n  // Deployment to Azure functions might fail if\n  // you include too much resolvers (means your app is too big)\n  resolvers: [\n    UserResolver,\n    AccountResolver,\n    // your other resolvers\n  ],\n\n  // Only build the GraphQL schema locally\n  // The resulting schema.graphql will be generated to the following path:\n  // Path: /YOUR_PROJECT/src/schema.graphql\n  emitSchemaFile: process.env.NODE_ENV === \"local\" ? path.resolve(\"./src/schema.graphql\") : false,\n  container: Container,\n  validate: true,\n});\n\n// Add schema into Apollo Server\nconst server = new ApolloServer({\n  // include your schema\n  schema,\n\n  // only allow introspection in non-prod environments\n  introspection: process.env.NODE_ENV !== \"production\",\n\n  // you can handle errors in your own styles\n  formatError: (err: GraphQLFormattedError) => err,\n});\n\n// Start the server(less handler/function)\nexport default startServerAndCreateHandler(server);\n```\n\nEach Azure Function needs to have an equivalent configuration file called `function.json`, here's how you can configure it:\n\n```json\n// function.json\n\n{\n  \"bindings\": [\n    {\n      \"authLevel\": \"anonymous\",\n      \"type\": \"httpTrigger\",\n      \"direction\": \"in\",\n      \"name\": \"req\",\n      \"route\": \"graphql\",\n      \"methods\": [\"get\", \"post\", \"options\"]\n    },\n    {\n      \"type\": \"http\",\n      \"direction\": \"out\",\n      \"name\": \"$return\"\n    }\n  ],\n  \"scriptFile\": \"../dist/handler-graphql/index.js\"\n}\n```\n\nFor better maintainability of your codebase, we recommend separate your Azure Functions into its own folders, away from the actual GraphQL Resolvers. Here's an example:\n\n```text\n/YOUR_PROJECT\n  /handlers\n    /handler-graphql\n      index.ts\n      function.json\n    /handler-SOME-OTHER-FUNCTION-1\n      index.ts\n      function.json\n    /handler-SOME-OTHER-FUNCTION-2\n      index.ts\n      function.json\n\n  /src\n    /resolvers\n      user.resolver.ts\n      account.resolver.ts\n    /services\n      user.service.ts\n      account.service.ts\n\n  package.json\n  host.json\n  .eslintrc.js\n  .prettierrc\n  .eslintignore\n  .prettierignore\n\netc etc etc...\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/browser-usage.md",
    "content": "---\ntitle: Browser usage\nid: version-2.0.0-rc.2-browser-usage\noriginal_id: browser-usage\n---\n\n## Using classes in a client app\n\nSometimes 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.\n\nSince 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.\n\nThe steps to accomplish this are different, depending on the framework, bundler or compiler we use.\nHowever, 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.\n\n## CRA and similar\n\nWe simply add this plugin code to our webpack config:\n\n```js\nmodule.exports = {\n  // ... Rest of Webpack configuration\n  plugins: [\n    // ... Other existing plugins\n    new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {\n      resource.request = resource.request.replace(/type-graphql/, \"type-graphql/shim\");\n    }),\n  ];\n}\n```\n\nIn 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.\n\n## Angular and similar\n\nIn 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:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"node_modules/type-graphql/build/typings/shim.ts\"]\n    }\n  }\n}\n```\n\n## Next.js and similar\n\nWhen 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.\n\nThe easiest way is to accomplish this is also done in `tsconfig.json` - add the same keys like in the example before to `compilerOptions`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"type-graphql\": [\"node_modules/type-graphql/build/typings/shim.ts\"]\n    }\n  }\n}\n```\n\nThen, `npm install -D tsconfig-paths` and enable it with `NODE_OPTIONS=\"-r tsconfig-paths/register\"` in our environment variables setup.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-rc.2-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-rc.2-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports three kinds of custom decorators - method, resolver class and parameter.\n\n## Method decorators\n\nUsing [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.\n\nThey work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodMiddlewareDecorator` helper function with our middleware logic and return its value:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Resolver class decorators\n\nSimilar to method decorators, we can create our own custom resolver class decorators.\nIn this case we need to call `createResolverClassMiddlewareDecorator` helper function, just like we did for `createMethodMiddlewareDecorator`:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createResolverClassMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe usage is then analogue - we just place it above the resolver class and pass the required arguments to it:\n\n```ts\n@ValidateArgs(MyArgsSchema) // Custom decorator\n@UseMiddleware(ResolveTime) // Explicit middleware\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\nThis way, we just need to put it once in the code and our custom decorator will be applied to all the resolver's queries or mutations. As simple as that!\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParameterDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParameterDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n### Custom `@Arg` decorator\n\nIn some cases we might want to create a custom decorator that will also register/expose an argument in the GraphQL schema.\nCalling both `Arg()` and `createParameterDecorator()` inside a custom decorator does not play well with the internals of TypeGraphQL.\n\nHence, the `createParameterDecorator()` function supports second argument, `CustomParameterOptions` which allows to set decorator metadata for `@Arg` under the `arg` key:\n\n```ts\nfunction RandomIdArg(argName = \"id\") {\n  return createParameterDecorator(\n    // here we do the logic of getting provided argument or generating a random one\n    ({ args }) => args[argName] ?? Math.round(Math.random() * MAX_ID_VALUE),\n    {\n      // here we provide the metadata to register the parameter as a GraphQL argument\n      arg: {\n        name: argName,\n        typeFunc: () => Int,\n        options: {\n          nullable: true,\n          description: \"Accepts provided id or generates a random one.\",\n        },\n      },\n    },\n  );\n}\n```\n\nThe usage of that custom decorator is very similar to the previous one and `@Arg` decorator itself:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    // custom decorator that will expose an arg in the schema\n    @RandomIdArg(\"id\") id: number,\n  ) {\n    return await this.recipesRepository.findById(id);\n  }\n}\n```\n\n## Example\n\nSee 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.2/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-rc.2-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/using-container).\n\nFor 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.2/examples/using-scoped-container).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-rc.2-examples\noriginal_id: examples\n---\n\nOn 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.2/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-rc.2-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-rc.2-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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.2/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-rc.2-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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.2/examples/interfaces-inheritance).\n\nFor a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/resolvers-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-rc.2-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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.2/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-rc.2-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo attach middleware to a resolver method, place the `@UseMiddleware()` decorator above the method 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nIf we want to apply the middlewares to all the resolver's class methods, we can put the decorator on top of the class declaration:\n\n```ts\n@UseMiddleware(ResolveTime, LogAccess)\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(): number {\n    return Math.random();\n  }\n\n  @Query()\n  constantValue(): number {\n    return 21.37;\n  }\n}\n```\n\n> Be aware that resolver's class middlewares are executed first, before the method's ones.\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middlewares like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field, method or resolver class.\n\nHence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and a field. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-rc.2-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-rc.2-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo 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/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ root, args, context, info }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, 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.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscriptions\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput, @PubSub() pubSub: PubSubEngine) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> 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.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package.\n\nFor 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.2/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-rc.2-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.2/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-rc.2-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.2/examples/custom-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-rc.3-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## Declaration\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nHowever, declaring `@Authorized()` on all the resolver's class methods would be not only a tedious task but also an error-prone one, as it's easy to forget to put it on some newly added method, etc.\nHence, TypeGraphQL support declaring `@Authorized()` or the resolver class level. This way you can declare it once per resolver's class but you can still overwrite the defaults and narrows the authorization rules:\n\n```ts\n@Authorized()\n@Resolver()\nclass MyResolver {\n  // this will inherit the auth guard defined on the class level\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  // this one overwrites the resolver's one\n  // and registers roles required for this mutation\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\n## Runtime checks\n\nHaving all the metadata for authorization set, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-rc.3-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-rc.3-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports three kinds of custom decorators - method, resolver class and parameter.\n\n## Method decorators\n\nUsing [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.\n\nThey work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodMiddlewareDecorator` helper function with our middleware logic and return its value:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Resolver class decorators\n\nSimilar to method decorators, we can create our own custom resolver class decorators.\nIn this case we need to call `createResolverClassMiddlewareDecorator` helper function, just like we did for `createMethodMiddlewareDecorator`:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createResolverClassMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe usage is then analogue - we just place it above the resolver class and pass the required arguments to it:\n\n```ts\n@ValidateArgs(MyArgsSchema) // Custom decorator\n@UseMiddleware(ResolveTime) // Explicit middleware\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\nThis way, we just need to put it once in the code and our custom decorator will be applied to all the resolver's queries or mutations. As simple as that!\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParameterDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParameterDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n### Custom `@Arg` decorator\n\nIn some cases we might want to create a custom decorator that will also register/expose an argument in the GraphQL schema.\nCalling both `Arg()` and `createParameterDecorator()` inside a custom decorator does not play well with the internals of TypeGraphQL.\n\nHence, the `createParameterDecorator()` function supports second argument, `CustomParameterOptions` which allows to set decorator metadata for `@Arg` under the `arg` key:\n\n```ts\nfunction RandomIdArg(argName = \"id\") {\n  return createParameterDecorator(\n    // here we do the logic of getting provided argument or generating a random one\n    ({ args }) => args[argName] ?? Math.round(Math.random() * MAX_ID_VALUE),\n    {\n      // here we provide the metadata to register the parameter as a GraphQL argument\n      arg: {\n        name: argName,\n        typeFunc: () => Int,\n        options: {\n          nullable: true,\n          description: \"Accepts provided id or generates a random one.\",\n        },\n      },\n    },\n  );\n}\n```\n\nThe usage of that custom decorator is very similar to the previous one and `@Arg` decorator itself:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    // custom decorator that will expose an arg in the schema\n    @RandomIdArg(\"id\") id: number,\n  ) {\n    return await this.recipesRepository.findById(id);\n  }\n}\n```\n\n## Example\n\nSee 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.3/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-rc.3-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/using-container).\n\nFor 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.3/examples/using-scoped-container).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/emit-schema.md",
    "content": "---\ntitle: Emitting the schema SDL\nid: version-2.0.0-rc.3-emit-schema\noriginal_id: emit-schema\n---\n\nTypeGraphQL'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.\n\nThe 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.\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [ExampleResolver],\n  // Automatically create `schema.graphql` file with schema definition in project's working directory\n  emitSchemaFile: true,\n  // Or create the file with schema in selected path\n  emitSchemaFile: path.resolve(__dirname, \"__snapshots__/schema/schema.graphql\"),\n  // Or pass a config object\n  emitSchemaFile: {\n    path: __dirname + \"/schema.graphql\",\n    sortedSchema: false, // By default the printed schema is sorted alphabetically\n  },\n});\n```\n\nThe 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.\n\n```ts\nimport { emitSchemaDefinitionFile } from \"type-graphql\";\n\n// ...\nhypotheticalFileWatcher.watch(\"./src/**/*.{resolver,type,input,arg}.ts\", async () => {\n  const schema = getSchemaNotFromBuildSchemaFunction();\n  await emitSchemaDefinitionFile(\"/path/to/folder/schema.graphql\", schema);\n});\n```\n\n## Emit schema with custom directives\n\nCurrently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`.\n\nIf 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.\n\nBelow there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils):\n\n```ts\nimport { GraphQLSchema, lexicographicSortSchema } from \"graphql\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport fs from \"node:fs/promises\";\n\nexport async function emitSchemaDefinitionWithDirectivesFile(\n  schemaFilePath: string,\n  schema: GraphQLSchema,\n): Promise<void> {\n  const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema));\n  await fs.writeFile(schemaFilePath, schemaFileContent);\n}\n```\n\nThe usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`:\n\n```ts\nconst schema = await buildSchema(/*...*/);\n\nawait emitSchemaDefinitionWithDirectivesFile(\"/path/to/folder/schema.graphql\", schema);\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-rc.3-examples\noriginal_id: examples\n---\n\nOn 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.3/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-rc.3-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see [more detailed examples of usage here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-rc.3-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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.3/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-rc.3-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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.3/examples/interfaces-inheritance).\n\nFor a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/resolvers-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/installation.md",
    "content": "---\ntitle: Installation\nid: version-2.0.0-rc.3-installation\noriginal_id: installation\n---\n\nBefore getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project.\n\n> **Prerequisites**\n>\n> Before we begin, we must make sure our development environment includes Node.js and npm.\n\n## Packages installation\n\nFirst, 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:\n\n```sh\nnpm install graphql graphql-scalars type-graphql\n```\n\nAlso, the `Reflect.metadata()` shim is required to make the type reflection work:\n\n```sh\nnpm install reflect-metadata\n# or\nnpm install core-js\n```\n\nWe must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers):\n\n```ts\nimport \"reflect-metadata\";\n// or\nimport \"core-js/features/reflect\";\n```\n\n## TypeScript configuration\n\nIt's important to set these options in the `tsconfig.json` file of our project:\n\n```json\n{\n  \"emitDecoratorMetadata\": true,\n  \"experimentalDecorators\": true\n}\n```\n\n`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:\n\n```js\n{\n  \"target\": \"es2021\" // Or newer if Node.js version supports it\n}\n```\n\nAll in all, the minimal `tsconfig.json` file example looks like this:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2021\",\n    \"module\": \"commonjs\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-rc.3-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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.3/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-rc.3-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo attach middleware to a resolver method, place the `@UseMiddleware()` decorator above the method 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nIf we want to apply the middlewares to all the resolver's class methods, we can put the decorator on top of the class declaration:\n\n```ts\n@UseMiddleware(ResolveTime, LogAccess)\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(): number {\n    return Math.random();\n  }\n\n  @Query()\n  constantValue(): number {\n    return 21.37;\n  }\n}\n```\n\n> Be aware that resolver's class middlewares are executed first, before the method's ones.\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middlewares like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field, method or resolver class.\n\nHence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and a field. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-rc.3-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-rc.3-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscription`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ root, args, context, info }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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/subscription` package.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscription` package. Optionally, we can define the used topics and payload type using the type argument, e.g.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscription\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscription` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscription`, the second argument might be treated as a payload, not dynamic topic id.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscription` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package.\n\nFor 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.3/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-rc.3-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.3/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-rc.3-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.3/examples/custom-validation).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/authorization.md",
    "content": "---\ntitle: Authorization\nid: version-2.0.0-rc.4-authorization\noriginal_id: authorization\n---\n\nAuthorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users.\n\nIn 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.\n\nThat's why authorization is a first-class feature in `TypeGraphQL`!\n\n## Declaration\n\nFirst, we need to use the `@Authorized` decorator as a guard on a field, query or mutation.\nExample object type field guards:\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field()\n  publicField: string;\n\n  @Authorized()\n  @Field()\n  authorizedField: string;\n\n  @Authorized(\"ADMIN\")\n  @Field()\n  adminField: string;\n\n  @Authorized([\"ADMIN\", \"MODERATOR\"])\n  @Field({ nullable: true })\n  hiddenField?: string;\n}\n```\n\nWe 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.\nBy default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized<number>(1, 7, 22)`.\n\nThus, 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.\n\nSample query and mutation guards:\n\n```ts\n@Resolver()\nclass MyResolver {\n  @Query()\n  publicQuery(): MyObject {\n    return {\n      publicField: \"Some public data\",\n      authorizedField: \"Data for logged users only\",\n      adminField: \"Top secret info for admin\",\n    };\n  }\n\n  @Authorized()\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\nAuthorized 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`.\n\nHowever, declaring `@Authorized()` on all the resolver's class methods would be not only a tedious task but also an error-prone one, as it's easy to forget to put it on some newly added method, etc.\nHence, TypeGraphQL support declaring `@Authorized()` or the resolver class level. This way you can declare it once per resolver's class but you can still overwrite the defaults and narrows the authorization rules:\n\n```ts\n@Authorized()\n@Resolver()\nclass MyResolver {\n  // this will inherit the auth guard defined on the class level\n  @Query()\n  authedQuery(): string {\n    return \"Authorized users only!\";\n  }\n\n  // this one overwrites the resolver's one\n  // and registers roles required for this mutation\n  @Authorized(\"ADMIN\", \"MODERATOR\")\n  @Mutation()\n  adminMutation(): string {\n    return \"You are an admin/moderator, you can safely drop the database ;)\";\n  }\n}\n```\n\n## Runtime checks\n\nHaving all the metadata for authorization set, we need to create our auth checker function. Its implementation may depend on our business logic:\n\n```ts\nexport const customAuthChecker: AuthChecker<ContextType> = (\n  { root, args, context, info },\n  roles,\n) => {\n  // Read user from context\n  // and check the user's permission against the `roles` argument\n  // that comes from the '@Authorized' decorator, eg. [\"ADMIN\", \"MODERATOR\"]\n\n  return true; // or 'false' if access is denied\n};\n```\n\nThe second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type.\n\nAuth checker can be also defined as a class - this way we can leverage the dependency injection mechanism:\n\n```ts\nexport class CustomAuthChecker implements AuthCheckerInterface<ContextType> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  check({ root, args, context, info }: ResolverData<ContextType>, roles: string[]) {\n    const userId = getUserIdFromToken(context.token);\n    // Use injected service\n    const user = this.userRepository.getById(userId);\n\n    // Custom logic, e.g.:\n    return user % 2 === 0;\n  }\n}\n```\n\nThe last step is to register the function or class while building the schema:\n\n```ts\nimport { customAuthChecker } from \"../auth/custom-auth-checker.ts\";\n\nconst schema = await buildSchema({\n  resolvers: [MyResolver],\n  // Register the auth checking function\n  // or defining it inline\n  authChecker: customAuthChecker,\n});\n```\n\nAnd it's done! 😉\n\nIf 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\"`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [\"./**/*.resolver.ts\"],\n  authChecker: customAuthChecker,\n  authMode: \"null\",\n});\n```\n\nIt will then return `null` instead of throwing an authorization error.\n\n## Recipes\n\nWe can also use `TypeGraphQL` with JWT authentication.\nHere's an example using `@apollo/server`:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { expressMiddleware } from \"@apollo/server/express4\";\nimport express from \"express\";\nimport jwt from \"express-jwt\";\nimport bodyParser from \"body-parser\";\nimport { schema } from \"./graphql/schema\";\nimport { User } from \"./User.type\";\n\n// GraphQL path\nconst GRAPHQL_PATH = \"/graphql\";\n\n// GraphQL context\ntype Context = {\n  user?: User;\n};\n\n// Express\nconst app = express();\n\n// Apollo server\nconst server = new ApolloServer<Context>({ schema });\nawait server.start();\n\n// Mount a JWT or other authentication middleware that is run before the GraphQL execution\napp.use(\n  GRAPHQL_PATH,\n  jwt({\n    secret: \"TypeGraphQL\",\n    credentialsRequired: false,\n  }),\n);\n\n// Apply GraphQL server middleware\napp.use(\n  GRAPHQL_PATH,\n  bodyParser.json(),\n  expressMiddleware(server, {\n    // Build context\n    // 'req.user' comes from 'express-jwt'\n    context: async ({ req }) => ({ user: req.user }),\n  }),\n);\n\n// Start server\nawait new Promise<void>(resolve => app.listen({ port: 4000 }, resolve));\nconsole.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`);\n```\n\nThen we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism.\n\n## Example\n\nSee how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/authorization).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/complexity.md",
    "content": "---\ntitle: Query complexity\nid: version-2.0.0-rc.4-complexity\noriginal_id: complexity\n---\n\nA 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).\n\nThis 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`.\n\nAll 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.\n\n## How to use\n\nFirst, we need to pass `complexity` as an option to the decorator on a field, query or mutation.\n\nExample of complexity\n\n```ts\n@ObjectType()\nclass MyObject {\n  @Field({ complexity: 2 })\n  publicField: string;\n\n  @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 })\n  complexField: string;\n}\n```\n\nThe `complexity` option may be omitted if the complexity value is 1.\nComplexity 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.\n\nIn the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP.\nYou 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:\n\n```ts\nasync function bootstrap() {\n  // ... Build GraphQL schema\n\n  // Create GraphQL server\n  const server = new ApolloServer({\n    schema,\n    // Create a plugin to allow query complexity calculation for every request\n    plugins: [\n      {\n        requestDidStart: async () => ({\n          async didResolveOperation({ request, document }) {\n            /**\n             * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server\n             * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks\n             * More documentation can be found at https://github.com/ivome/graphql-query-complexity\n             */\n            const complexity = getComplexity({\n              // GraphQL schema\n              schema,\n              // To calculate query complexity properly,\n              // check only the requested operation\n              // not the whole document that may contains multiple operations\n              operationName: request.operationName,\n              // GraphQL query document\n              query: document,\n              // GraphQL query variables\n              variables: request.variables,\n              // Add any number of estimators. The estimators are invoked in order, the first\n              // numeric value that is being returned by an estimator is used as the field complexity\n              // If no estimator returns a value, an exception is raised\n              estimators: [\n                // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql\n                fieldExtensionsEstimator(),\n                // Add more estimators here...\n                // This will assign each field a complexity of 1\n                // if no other estimator returned a value\n                simpleEstimator({ defaultComplexity: 1 }),\n              ],\n            });\n\n            // React to the calculated complexity,\n            // like compare it with max and throw error when the threshold is reached\n            if (complexity > MAX_COMPLEXITY) {\n              throw new Error(\n                `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`,\n              );\n            }\n            console.log(\"Used query complexity points:\", complexity);\n          },\n        }),\n      },\n    ],\n  });\n\n  // Start server\n  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });\n  console.log(`GraphQL server ready at ${url}`);\n}\n```\n\nAnd it's done! 😉\n\nFor more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity).\n\n## Example\n\nSee how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/query-complexity).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/custom-decorators.md",
    "content": "---\ntitle: Custom decorators\nid: version-2.0.0-rc.4-custom-decorators\noriginal_id: custom-decorators\n---\n\nCustom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports three kinds of custom decorators - method, resolver class and parameter.\n\n## Method decorators\n\nUsing [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.\n\nThey work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodMiddlewareDecorator` helper function with our middleware logic and return its value:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createMethodMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe 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:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @ValidateArgs(MyArgsSchema) // Custom decorator\n  @UseMiddleware(ResolveTime) // Explicit middleware\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\n## Resolver class decorators\n\nSimilar to method decorators, we can create our own custom resolver class decorators.\nIn this case we need to call `createResolverClassMiddlewareDecorator` helper function, just like we did for `createMethodMiddlewareDecorator`:\n\n```ts\nexport function ValidateArgs(schema: JoiSchema) {\n  return createResolverClassMiddlewareDecorator(async ({ args }, next) => {\n    // Middleware code that uses custom decorator arguments\n\n    // e.g. Validation logic based on schema using 'joi'\n    await joiValidate(schema, args);\n    return next();\n  });\n}\n```\n\nThe usage is then analogue - we just place it above the resolver class and pass the required arguments to it:\n\n```ts\n@ValidateArgs(MyArgsSchema) // Custom decorator\n@UseMiddleware(ResolveTime) // Explicit middleware\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(@Args() { scale }: MyArgs): number {\n    return Math.random() * scale;\n  }\n}\n```\n\nThis way, we just need to put it once in the code and our custom decorator will be applied to all the resolver's queries or mutations. As simple as that!\n\n## Parameter decorators\n\nParameter 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.\n\nThey might be just a simple data extractor function, that makes our resolver more unit test friendly:\n\n```ts\nfunction CurrentUser() {\n  return createParameterDecorator<MyContextType>(({ context }) => context.currentUser);\n}\n```\n\nOr 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):\n\n```ts\nfunction Fields(level = 1): ParameterDecorator {\n  return createParameterDecorator(async ({ info }) => {\n    const fieldsMap: FieldsMap = {};\n    // Calculate an object with info about requested fields\n    // based on GraphQL 'info' parameter of the resolver and the level parameter\n    // or even call some async service, as it can be a regular async function and we can just 'await'\n    return fieldsMap;\n  });\n}\n```\n\n> 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.\n\nThen we can use our custom param decorators in the resolvers just like the built-in decorators:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Authorized()\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Args() recipeData: AddRecipeInput,\n    // Custom decorator just like the built-in one\n    @CurrentUser() currentUser: User,\n  ) {\n    const recipe: Recipe = {\n      ...recipeData,\n      // and use the data returned from custom decorator in the resolver code\n      author: currentUser,\n    };\n    await this.recipesRepository.save(recipe);\n\n    return recipe;\n  }\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    @Arg(\"id\") id: string,\n    // Custom decorator that parses the fields from GraphQL query info\n    @Fields() fields: FieldsMap,\n  ) {\n    return await this.recipesRepository.find(id, {\n      // use the fields map as a select projection to optimize db queries\n      select: fields,\n    });\n  }\n}\n```\n\n### Custom `@Arg` decorator\n\nIn some cases we might want to create a custom decorator that will also register/expose an argument in the GraphQL schema.\nCalling both `Arg()` and `createParameterDecorator()` inside a custom decorator does not play well with the internals of TypeGraphQL.\n\nHence, the `createParameterDecorator()` function supports second argument, `CustomParameterOptions` which allows to set decorator metadata for `@Arg` under the `arg` key:\n\n```ts\nfunction RandomIdArg(argName = \"id\") {\n  return createParameterDecorator(\n    // here we do the logic of getting provided argument or generating a random one\n    ({ args }) => args[argName] ?? Math.round(Math.random() * MAX_ID_VALUE),\n    {\n      // here we provide the metadata to register the parameter as a GraphQL argument\n      arg: {\n        name: argName,\n        typeFunc: () => Int,\n        options: {\n          nullable: true,\n          description: \"Accepts provided id or generates a random one.\",\n        },\n      },\n    },\n  );\n}\n```\n\nThe usage of that custom decorator is very similar to the previous one and `@Arg` decorator itself:\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  constructor(private readonly recipesRepository: Repository<Recipe>) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(\n    // custom decorator that will expose an arg in the schema\n    @RandomIdArg(\"id\") id: number,\n  ) {\n    return await this.recipesRepository.findById(id);\n  }\n}\n```\n\n## Example\n\nSee 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.4/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/dependency-injection.md",
    "content": "---\ntitle: Dependency injection\nid: version-2.0.0-rc.4-dependency-injection\noriginal_id: dependency-injection\n---\n\nDependency injection is a really useful pattern that helps in decoupling parts of the app.\n\nTypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework.\n\n## Basic usage\n\nThe usage of this feature is very simple - all you need to do is register a 3rd party container.\n\nExample using TypeDI:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\n// IOC container\nimport { Container } from \"typedi\";\nimport { SampleResolver } from \"./resolvers\";\n\n// Build TypeGraphQL executable schema\nconst schema = await buildSchema({\n  // Array of resolvers\n  resolvers: [SampleResolver],\n  // Registry 3rd party IOC container\n  container: Container,\n});\n```\n\nResolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them:\n\n```ts\nimport { Service } from \"typedi\";\n\n@Service()\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  constructor(\n    // Dependency injection\n    private readonly recipeService: RecipeService,\n  ) {}\n\n  @Query(returns => Recipe, { nullable: true })\n  async recipe(@Arg(\"recipeId\") recipeId: string) {\n    // Usage of the injected service\n    return this.recipeService.getOne(recipeId);\n  }\n}\n```\n\nA sample recipe service implementation may look like this:\n\n```ts\nimport { Service, Inject } from \"typedi\";\n\n@Service()\nexport class RecipeService {\n  @Inject(\"SAMPLE_RECIPES\")\n  private readonly items: Recipe[],\n\n  async getAll() {\n    return this.items;\n  }\n\n  async getOne(id: string) {\n    return this.items.find(item => item.id === id);\n  }\n}\n```\n\n> 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.:\n>\n> ```ts\n> container.bind<SampleResolver>(SampleResolver).to(SampleResolver).inSingletonScope();\n> ```\n\n## Scoped containers\n\nDependency 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.\n\nTo register a scoped container, we need to make some changes in the server bootstrapping config code.\nFirst 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.\n\nFor simple container libraries we may define it inline, e.g. using `TypeDI`:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => Container.of(context.requestId));\n};\n```\n\nThe 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`.\n\nFor 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:\n\n```ts\nawait buildSchema({\n  container: (({ context }: ResolverData<TContext>) => context.container);\n};\n```\n\nExample using `TypeDI` and `@apollo/server` with the `context` creation method:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\n// Create GraphQL server\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n});\n\n// Start server\nconst { url } = await startStandaloneServer(server, {\n  listen: { port: 4000 },\n  // Provide unique context with 'requestId' for each request\n  context: async () => {\n    const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like\n    const container = Container.of(requestId.toString()); // Get scoped container\n    const context = { requestId, container }; // Create context\n    container.set(\"context\", context); // Set context or other data in container\n\n    return context;\n  },\n});\nconsole.log(`GraphQL server ready at ${url}`);\n```\n\nWe 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.\n\nApollo 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.\n\nExample using `TypeDI` and `@apollo/server` with plugins approach:\n\n```ts\nimport { ApolloServer } from \"@apollo/server\";\nimport { startStandaloneServer } from \"@apollo/server/standalone\";\nimport { Container } from \"typedi\";\n\nconst server = new ApolloServer({\n  // GraphQL schema\n  schema,\n  // Create a plugin to allow for disposing the scoped container created for every request\n  plugins: [\n    {\n      requestDidStart: async () => ({\n        async willSendResponse(requestContext) {\n          // Dispose the scoped container to prevent memory leaks\n          Container.reset(requestContext.contextValue.requestId.toString());\n\n          // For developers curiosity purpose, here is the logging of current scoped container instances\n          // Make multiple parallel requests to see in console how this works\n          const instancesIds = ((Container as any).instances as ContainerInstance[]).map(\n            instance => instance.id,\n          );\n          console.log(\"Instances left in memory: \", instancesIds);\n        },\n      }),\n    },\n  ],\n});\n```\n\nAnd 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.\n\nThe 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).\n\n> 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!\n\n## Example\n\nYou can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/using-container).\n\nFor 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.4/examples/using-scoped-container).\n\nIntegration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/tsyringe).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/examples.md",
    "content": "---\ntitle: Examples\nsidebar_label: List of examples\nid: version-2.0.0-rc.4-examples\noriginal_id: examples\n---\n\nOn 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.4/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries.\n\nTo run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`).\n\nEach subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio (<http://localhost:4000>) and play with them by modifying their shape and data.\n\n## Basics\n\n- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/simple-usage)\n\n## Advanced\n\n- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/enums-and-unions)\n- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/simple-subscriptions)\n- [Subscriptions (using Redis) \\*\\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/redis-subscriptions)\n- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/interfaces-inheritance)\n- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/extensions)\n\n## Features usage\n\n- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/using-container)\n  - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/using-scoped-container)\n- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/authorization)\n- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/automatic-validation)\n  - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/custom-validation)\n- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/interfaces-inheritance)\n- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/resolvers-inheritance)\n- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/generic-types)\n- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/mixin-classes)\n- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/middlewares-custom-decorators)\n- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/query-complexity)\n\n## 3rd party libs integration\n\n- [TypeORM (manual, synchronous) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/typeorm-basic-usage)\n- [TypeORM (automatic, lazy relations) \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/typeorm-lazy-relations)\n- [MikroORM \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/mikro-orm)\n- [Typegoose \\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/typegoose)\n- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/apollo-federation)\n- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/apollo-federation-2)\n- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/apollo-cache)\n- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/graphql-scalars)\n- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/tsyringe)\n\n_\\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \\\n_\\*\\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/extensions.md",
    "content": "---\ntitle: Extensions\nid: version-2.0.0-rc.4-extensions\noriginal_id: extensions\n---\n\nThe `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property.\nAnnotating 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.\n\nFor 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.\n\n> 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.\n\n## Using the `@Extensions` decorator\n\nAdding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want:\n\n```ts\n@Extensions({ complexity: 2 })\n```\n\nWe can pass several fields to the decorator:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\", logLevel: 1 })\n```\n\nAnd 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:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logLevel: 1 })\n```\n\nIf we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence:\n\n```ts\n@Extensions({ logMessage: \"Restricted access\" })\n@Extensions({ logMessage: \"Another message\" })\n```\n\nThe above usage results in your GraphQL type having a `logMessage: \"Another message\"` property in its extensions.\n\nTypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator:\n\n- `@ObjectType`\n- `@InputType`\n- `@Field`\n- `@Query`\n- `@Mutation`\n- `@FieldResolver`\n\nSo 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:\n\n```ts\n@Extensions({ roles: [\"USER\"] })\n@ObjectType()\nclass Foo {\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Field()\n  field: string;\n}\n\n@ObjectType()\nclass Bar {\n  @Extensions({ roles: [\"USER\"] })\n  @Extensions({ visible: false, logMessage: \"User accessed restricted field\" })\n  @Field()\n  field: string;\n}\n\n@Resolver(of => Foo)\nclass FooBarResolver {\n  @Extensions({ roles: [\"USER\"] })\n  @Query()\n  foobar(@Arg(\"baz\") baz: string): string {\n    return \"foobar\";\n  }\n\n  @Extensions({ roles: [\"ADMIN\"] })\n  @FieldResolver()\n  bar(): string {\n    return \"foobar\";\n  }\n}\n```\n\n## Using the extensions data in runtime\n\nOnce 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.\n\nHere 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`:\n\n```ts\nexport class LoggerMiddleware implements MiddlewareInterface<Context> {\n  constructor(private readonly logger: Logger) {}\n\n  use({ info }: ResolverData, next: NextFn) {\n    // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value\n    const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {};\n\n    if (logMessage) {\n      this.logger.log(logMessage);\n    }\n\n    return next();\n  }\n}\n```\n\n## Examples\n\nYou can see [more detailed examples of usage here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/extensions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/generic-types.md",
    "content": "---\ntitle: Generic Types\nid: version-2.0.0-rc.4-generic-types\noriginal_id: generic-types\n---\n\n[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).\n\nHence TypeGraphQL also has support for describing generic GraphQL types.\n\n## How to?\n\nUnfortunately, 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.\n\n### Basic usage\n\nStart by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`:\n\n```ts\nexport default function PaginatedResponse() {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nTo achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAfter that, add fields like in a normal class but using the generic type and parameters:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    // Runtime argument\n    @Field(type => [TItemClass])\n    // Generic type\n    items: TItem[];\n\n    @Field(type => Int)\n    total: number;\n\n    @Field()\n    hasMore: boolean;\n  }\n  return PaginatedResponseClass;\n}\n```\n\nFinally, use the generic function factory to create a dedicated type class:\n\n```ts\n@ObjectType()\nclass PaginatedUserResponse extends PaginatedResponse(User) {\n  // Add more fields or overwrite the existing one's types\n  @Field(type => [String])\n  otherInfo: string[];\n}\n```\n\nAnd then use it in our resolvers:\n\n```ts\n@Resolver()\nclass UserResolver {\n  @Query()\n  users(): PaginatedUserResponse {\n    // Custom business logic,\n    // depending on underlying data source and libraries\n    return {\n      items,\n      total,\n      hasMore,\n      otherInfo,\n    };\n  }\n}\n```\n\n### Complex generic type values\n\nWhen 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.\n\nBasically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator.\nSo 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`:\n\n```ts\nexport default function PaginatedResponse<TItemsFieldValue extends object>(\n  itemsFieldValue: ClassType<TItemsFieldValue> | GraphQLScalarType | String | Number | Boolean,\n) {\n  @ObjectType()\n  abstract class PaginatedResponseClass {\n    @Field(type => [itemsFieldValue])\n    items: TItemsFieldValue[];\n\n    // ... Other fields\n  }\n  return PaginatedResponseClass;\n}\n```\n\nAnd then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type:\n\n```ts\n@ObjectType()\nclass PaginatedStringsResponse extends PaginatedResponse<string>(String) {\n  // ...\n}\n```\n\n### Types factory\n\nWe can also create a generic class without using the `abstract` keyword.\nBut 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.\n\nTo avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name:\n\n```ts\nexport default function PaginatedResponse<TItem extends object>(TItemClass: ClassType<TItem>) {\n  // Provide a unique type name used in schema\n  @ObjectType(`Paginated${TItemClass.name}Response`)\n  class PaginatedResponseClass {\n    // ...\n  }\n  return PaginatedResponseClass;\n}\n```\n\nThen, 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:\n\n```ts\nconst PaginatedUserResponse = PaginatedResponse(User);\ntype PaginatedUserResponse = InstanceType<typeof PaginatedUserResponse>;\n\n@Resolver()\nclass UserResolver {\n  // Provide a runtime type argument to the decorator\n  @Query(returns => PaginatedUserResponse)\n  users(): PaginatedUserResponse {\n    // Same implementation as in the earlier code snippet\n  }\n}\n```\n\n## Examples\n\nA 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.4/examples/generic-types).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/inheritance.md",
    "content": "---\ntitle: Inheritance\nid: version-2.0.0-rc.4-inheritance\noriginal_id: inheritance\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes.\n\n## Types inheritance\n\nOne of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy.\n\nWhile 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:\n\n```ts\n@ArgsType()\nclass PaginationArgs {\n  @Field(type => Int)\n  skip: number = 0;\n\n  @Field(type => Int)\n  take: number = 25;\n}\n```\n\nand then reuse it everywhere:\n\n```ts\n@ArgsType()\nclass GetTodosArgs extends PaginationArgs {\n  @Field()\n  onlyCompleted: boolean = false;\n}\n```\n\nThis technique also works with input type classes, as well as with object type classes:\n\n```ts\n@ObjectType()\nclass Person {\n  @Field()\n  age: number;\n}\n\n@ObjectType()\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nNote 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()`.\n\n## Resolver Inheritance\n\nA 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.\n\nSince we need to generate unique query/mutation names, we have to create a factory function for our base class:\n\n```ts\nfunction createBaseResolver() {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nBe 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.\n\nThis 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nIt's very important to mark the `BaseResolver` class using the `@Resolver` decorator:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {}\n\n  return BaseResolver;\n}\n```\n\nWe 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:\n\n```ts\nfunction createBaseResolver<T extends ClassType>(suffix: string, objectTypeCls: T) {\n  @Resolver()\n  abstract class BaseResolver {\n    protected items: T[] = [];\n\n    @Query(type => [objectTypeCls], { name: `getAll${suffix}` })\n    async getAll(@Arg(\"first\", type => Int) first: number): Promise<T[]> {\n      return this.items.slice(0, first);\n    }\n  }\n\n  return BaseResolver;\n}\n```\n\nNow we can create a specific resolver class that will extend the base resolver class:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  // ...\n}\n```\n\nWe can also add specific queries and mutations in our resolver class, as always:\n\n```ts\nconst PersonBaseResolver = createBaseResolver(\"person\", Person);\n\n@Resolver(of => Person)\nexport class PersonResolver extends PersonBaseResolver {\n  @Mutation()\n  addPerson(@Arg(\"input\") personInput: PersonInput): Person {\n    this.items.push(personInput);\n    return personInput;\n  }\n}\n```\n\nAnd that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly.\n\nWe 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.\n\n## Examples\n\nMore 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.4/examples/interfaces-inheritance).\n\nFor a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/resolvers-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/interfaces.md",
    "content": "---\ntitle: Interfaces\nid: version-2.0.0-rc.4-interfaces\noriginal_id: interfaces\n---\n\nThe main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes.\n\nIn 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.\n\nRead more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).\n\n## Abstract classes\n\nTypeScript 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.\n\nLuckily, 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.\n\n## Defining interface type\n\nHow 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field(type => ID)\n  id: string;\n\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nWe can then use this interface type class like an interface in the object type class definition:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  id: string;\n  name: string;\n  age: number;\n}\n```\n\nThe 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] })`.\n\nIt 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.\n\nWe can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  @Field()\n  hasKids: boolean;\n}\n```\n\n## Implementing other interfaces\n\nSince `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).\n\nTo accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option:\n\n```ts\n@InterfaceType()\nclass Node {\n  @Field(type => ID)\n  id: string;\n}\n\n@InterfaceType({ implements: Node })\nclass Person extends Node {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nAlso, 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.:\n\n```ts\n@ObjectType({ implements: [Person] })\nclass Student extends Person {\n  @Field()\n  universityName: string;\n}\n```\n\nThis example produces following representation in GraphQL SDL:\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ninterface Person implements Node {\n  id: ID!\n  name: String!\n  age: Int!\n}\n\ntype Student implements Node & Person {\n  id: ID!\n  name: String!\n  age: Int!\n  universityName: String!\n}\n```\n\n## Resolvers and arguments\n\nWhat's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  firstName: string;\n\n  @Field()\n  lastName: string;\n\n  @Field()\n  fullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\n\nThey're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields.\n\nAdditionally, if we want to declare that the interface accepts some arguments, e.g.:\n\n```graphql\ninterface IPerson {\n  avatar(size: Int!): String!\n}\n```\n\nWe can just use `@Arg` or `@Args` decorators as usual:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nUnfortunately, TypeScript doesn't allow using decorators on abstract methods.\nSo 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:\n\n```ts\n@InterfaceType()\nabstract class IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number): string {\n    throw new Error(\"Method not implemented!\");\n  }\n}\n```\n\nAnd 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:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person extends IPerson {\n  avatar(size: number): string {\n    return `http://i.pravatar.cc/${size}`;\n  }\n}\n```\n\nIn order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature:\n\n```ts\n@ObjectType({ implements: IPerson })\nclass Person implements IPerson {\n  @Field()\n  avatar(@Arg(\"size\") size: number, @Arg(\"format\") format: string): string {\n    return `http://i.pravatar.cc/${size}.${format}`;\n  }\n}\n```\n\nResolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator:\n\n```ts\n@Resolver(of => IPerson)\nclass IPersonResolver {\n  @FieldResolver()\n  avatar(@Root() person: IPerson, @Arg(\"size\") size: number): string {\n    return `http://typegraphql.com/${person.id}/${size}`;\n  }\n}\n```\n\n## Registering in schema\n\nBy 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.\n\nHowever, 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).\n\nIn this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema:\n\n```ts\n@InterfaceType({ autoRegisterImplementations: false })\nabstract class Node {\n  @Field(type => ID)\n  id: string;\n}\n```\n\nThen 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`:\n\n```ts\nconst schema = await buildSchema({\n  resolvers,\n  // Provide orphaned object types\n  orphanedTypes: [Person, Animal, Recipe],\n});\n```\n\nBe 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.\n\n## Resolving Type\n\nBe 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.\n\nWe 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.:\n\n```ts\n@InterfaceType({\n  resolveType: value => {\n    if (\"grades\" in value) {\n      return \"Student\"; // Schema name of type string\n    }\n    return Person; // Or object type class\n  },\n})\nabstract class IPerson {\n  // ...\n}\n```\n\nHowever 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.\n\n## Examples\n\nFor 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.4/examples/interfaces-inheritance).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/middlewares.md",
    "content": "---\ntitle: Middleware and guards\nid: version-2.0.0-rc.4-middlewares\noriginal_id: middlewares\n---\n\nMiddleware 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.\n\n## Creating Middleware\n\n### What is Middleware?\n\nMiddleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments:\n\n- resolver data - the same as resolvers (`root`, `args`, `context`, `info`)\n- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached\n\nWe 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.\n\nThis makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement:\n\n```ts\nexport const ResolveTime: MiddlewareFn = async ({ info }, next) => {\n  const start = Date.now();\n  await next();\n  const resolveTime = Date.now() - start;\n  console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`);\n};\n```\n\n### Intercepting the execution result\n\nMiddleware 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:\n\n```ts\nexport const CompetitorInterceptor: MiddlewareFn = async (_, next) => {\n  const result = await next();\n  if (result === \"typegql\") {\n    return \"type-graphql\";\n  }\n  return result;\n};\n```\n\nIt 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.\n\n### Simple Middleware\n\nIf 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:\n\n```ts\nconst LogAccess: MiddlewareFn<TContext> = ({ context, info }, next) => {\n  const username: string = context.username || \"guest\";\n  console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n  return next();\n};\n```\n\n### Guards\n\nMiddleware 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.\n\nWe 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.\n\nThis way we can create a guard that blocks access to the resolver and prevents execution or any data return.\n\n```ts\nexport const CompetitorDetector: MiddlewareFn = async ({ args }, next) => {\n  if (args.frameworkName === \"type-graphql\") {\n    return \"TypeGraphQL\";\n  }\n  if (args.frameworkName === \"typegql\") {\n    throw new Error(\"Competitive framework detected!\");\n  }\n  return next();\n};\n```\n\n### Reusable Middleware\n\nSometimes 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.\n\n```ts\nexport function NumberInterceptor(minValue: number): MiddlewareFn {\n  return async (_, next) => {\n    const result = await next();\n    // Hide values below minValue\n    if (typeof result === \"number\" && result < minValue) {\n      return null;\n    }\n    return result;\n  };\n}\n```\n\nRemember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver!\n\n### Error Interceptors\n\nMiddleware 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:\n\n```ts\nexport const ErrorInterceptor: MiddlewareFn<any> = async ({ context, info }, next) => {\n  try {\n    return await next();\n  } catch (err) {\n    // Write error to file log\n    fileLog.write(err, context, info);\n\n    // Hide errors from db like printing sql query\n    if (someCondition(err)) {\n      throw new Error(\"Unknown error occurred!\");\n    }\n\n    // Rethrow the error\n    throw err;\n  }\n};\n```\n\n### Class-based Middleware\n\nSometimes 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.\n\nTo 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:\n\n```ts\nexport class LogAccess implements MiddlewareInterface<TContext> {\n  constructor(private readonly logger: Logger) {}\n\n  async use({ context, info }: ResolverData<TContext>, next: NextFn) {\n    const username: string = context.username || \"guest\";\n    this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`);\n    return next();\n  }\n}\n```\n\n## How to use\n\n### Attaching Middleware\n\nTo attach middleware to a resolver method, place the `@UseMiddleware()` decorator above the method 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):\n\n```ts\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  @UseMiddleware(ResolveTime, LogAccess)\n  randomValue(): number {\n    return Math.random();\n  }\n}\n```\n\nIf we want to apply the middlewares to all the resolver's class methods, we can put the decorator on top of the class declaration:\n\n```ts\n@UseMiddleware(ResolveTime, LogAccess)\n@Resolver()\nexport class RecipeResolver {\n  @Query()\n  randomValue(): number {\n    return Math.random();\n  }\n\n  @Query()\n  constantValue(): number {\n    return 21.37;\n  }\n}\n```\n\n> Be aware that resolver's class middlewares are executed first, before the method's ones.\n\nWe can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md).\n\n```ts\n@ObjectType()\nexport class Recipe {\n  @Field()\n  title: string;\n\n  @Field(type => [Int])\n  @UseMiddleware(LogAccess)\n  ratings: number[];\n}\n```\n\n### Global Middleware\n\nHowever, for common middlewares like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field, method or resolver class.\n\nHence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and a field. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  globalMiddlewares: [ErrorInterceptor, ResolveTime],\n});\n```\n\n### Custom Decorators\n\nIf 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).\n\n## Example\n\nSee how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/middlewares-custom-decorators).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/resolvers.md",
    "content": "---\ntitle: Resolvers\nid: version-2.0.0-rc.4-resolvers\noriginal_id: resolvers\n---\n\nBesides [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).\n\n## Queries and Mutations\n\n### Resolver classes\n\nFirst we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks:\n\n```ts\n@Resolver()\nclass RecipeResolver {}\n```\n\nWe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n}\n```\n\nThen 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:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  async recipes() {\n    // Fake async\n    return await this.recipesCollection;\n  }\n}\n```\n\nWe also need to do two things.\nThe first is to add the `@Query` decorator, which marks the class method as a GraphQL query.\nThe 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  private recipesCollection: Recipe[] = [];\n\n  @Query(returns => [Recipe])\n  async recipes() {\n    return await this.recipesCollection;\n  }\n}\n```\n\n### Arguments\n\nUsually, 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.\n\nFirst 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.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(\n    @Arg(\"servings\", { defaultValue: 2 }) servings: number,\n    @Arg(\"title\", { nullable: true }) title?: string,\n  ): Promise<Recipe[]> {\n    // ...\n  }\n}\n```\n\nThis 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.\n\n```ts\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { nullable: true })\n  skip?: number;\n\n  @Field(type => Int, { nullable: true })\n  take?: number;\n\n  @Field({ nullable: true })\n  title?: string;\n}\n```\n\nWe 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.\n\n> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`.\n> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only.\n\nAlso, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md).\n\nWe 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.\n\n```ts\nimport { Min, Max } from \"class-validator\";\n\n@ArgsType()\nclass GetRecipesArgs {\n  @Field(type => Int, { defaultValue: 0 })\n  @Min(0)\n  skip: number;\n\n  @Field(type => Int)\n  @Min(1)\n  @Max(50)\n  take = 25;\n\n  @Field({ nullable: true })\n  title?: string;\n\n  // Helpers - index calculations\n  get startIndex(): number {\n    return this.skip;\n  }\n  get endIndex(): number {\n    return this.skip + this.take;\n  }\n}\n```\n\nThen all that is left to do is use the args class as the type of the method parameter.\nWe can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object.\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Query(returns => [Recipe])\n  async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) {\n    // Example implementation\n    let recipes = this.recipesCollection;\n    if (title) {\n      recipes = recipes.filter(recipe => recipe.title === title);\n    }\n    return recipes.slice(startIndex, endIndex);\n  }\n}\n```\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ntype Query {\n  recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!]\n}\n```\n\n### Input types\n\nGraphQL 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:\n\n```ts\n@InputType()\nclass AddRecipeInput {}\n```\n\nTo ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type:\n\n```ts\n@InputType()\nclass AddRecipeInput implements Partial<Recipe> {}\n```\n\nWe then declare any input fields we need, using the `@Field()` decorator:\n\n```ts\n@InputType({ description: \"New recipe data\" })\nclass AddRecipeInput implements Partial<Recipe> {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\nAfter 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.\n\nWe may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface:\n\n```ts\n@Resolver()\nclass RecipeResolver {\n  // ...\n  @Mutation()\n  addRecipe(@Arg(\"data\") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe {\n    // Example implementation\n    const recipe = RecipesUtils.create(newRecipeData, ctx.user);\n    this.recipesCollection.push(recipe);\n    return recipe;\n  }\n}\n```\n\nBecause our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation.\n\nThis declaration will result in the following part of the schema in SDL:\n\n```graphql\ninput AddRecipeInput {\n  title: String!\n  description: String\n}\n```\n\n```graphql\ntype Mutation {\n  addRecipe(data: AddRecipeInput!): Recipe!\n}\n```\n\nBy 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.\n\n## Field resolvers\n\nQueries 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.\n\nField 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:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n}\n```\n\nThen we create a class method that will become the field resolver.\nIn our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  averageRating(recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nWe 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.\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nFor enhanced type safety we can implement the `ResolverInterface<Recipe>` interface.\nIt'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).\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    // ...\n  }\n}\n```\n\nHere is the full implementation of the sample `averageRating` field resolver:\n\n```ts\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  // Queries and mutations\n\n  @FieldResolver()\n  averageRating(@Root() recipe: Recipe) {\n    const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);\n    return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;\n  }\n}\n```\n\nFor simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition:\n\n```ts\n@ObjectType()\nclass Recipe {\n  @Field()\n  title: string;\n\n  @Field({ deprecationReason: \"Use `title` instead\" })\n  get name(): string {\n    return this.title;\n  }\n\n  @Field(type => [Rate])\n  ratings: Rate[];\n\n  @Field(type => Float, { nullable: true })\n  averageRating(@Arg(\"since\") sinceDate: Date): number | null {\n    const ratings = this.ratings.filter(rate => rate.date > sinceDate);\n    if (!ratings.length) return null;\n\n    const ratingsSum = ratings.reduce((a, b) => a + b, 0);\n    return ratingsSum / ratings.length;\n  }\n}\n```\n\nHowever, 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:\n\n```ts\nimport { Repository } from \"typeorm\";\n\n@Resolver(of => Recipe)\nclass RecipeResolver implements ResolverInterface<Recipe> {\n  constructor(\n    // Dependency injection\n    private readonly userRepository: Repository<User>,\n  ) {}\n\n  @FieldResolver()\n  async author(@Root() recipe: Recipe) {\n    const author = await this.userRepository.findById(recipe.userId);\n    if (!author) throw new SomethingWentWrongError();\n    return author;\n  }\n}\n```\n\nNote 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.\n\n## Resolver Inheritance\n\nResolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance).\n\n## Examples\n\nThese code samples are just made up for tutorial purposes.\nYou can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/subscriptions.md",
    "content": "---\ntitle: Subscriptions\nid: version-2.0.0-rc.4-subscriptions\noriginal_id: subscriptions\n---\n\nGraphQL can be used to perform reads with queries and writes with mutations.\nHowever, oftentimes clients want to get updates pushed to them from the server when data they care about changes.\nTo support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscription`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/).\n\n## Creating Subscriptions\n\nSubscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated.\n\nFirst we create a normal class method as always, but this time annotated with the `@Subscription()` decorator.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription()\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nThen 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\", // Single topic\n    topics: [\"NOTIFICATIONS\", \"ERRORS\"] // Or topics array\n    topics: ({ args, context }) => args.topic // Or dynamic topic function\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe can also provide the `filter` option to decide which topic events should trigger our subscription.\nThis function should return a `boolean` or `Promise<boolean>` type.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\nWe 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.\n\nAll we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise<AsyncIterable>`. Example using Prisma 1 subscription feature:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    subscribe: ({ root, args, context, info }) => {\n      return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] });\n    },\n  })\n  newNotification(): Notification {\n    // ...\n  }\n}\n```\n\n> 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/subscription` package.\n\nNow 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.\n\n```ts\nclass SampleResolver {\n  // ...\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    filter: ({ payload, args }) => args.priorities.includes(payload.priority),\n  })\n  newNotification(\n    @Root() notificationPayload: NotificationPayload,\n    @Args() args: NewNotificationsArgs,\n  ): Notification {\n    return {\n      ...notificationPayload,\n      date: new Date(),\n    };\n  }\n}\n```\n\n## Triggering subscription topics\n\nOk, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics?\n\nThey might be triggered from external sources like a database but also in mutations,\ne.g. when we modify some resource that clients want to receive notifications about when it changes.\n\nSo, let us assume we have this mutation for adding a new comment:\n\n```ts\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    return true;\n  }\n}\n```\n\nFirst, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscription` package. Optionally, we can define the used topics and payload type using the type argument, e.g.:\n\n```ts\nimport { createPubSub } from \"@graphql-yoga/subscription\";\n\nexport const pubSub = createPubSub<{\n  NOTIFICATIONS: [NotificationPayload];\n  DYNAMIC_ID_TOPIC: [number, NotificationPayload];\n}>();\n```\n\nThen, we need to register the `PubSub` instance in the `buildSchema()` function options:\n\n```ts\nimport { buildSchema } from \"type-graphql\";\nimport { pubSub } from \"./pubsub\";\n\nconst schema = await buildSchema({\n  resolver,\n  pubSub,\n});\n```\n\nFinally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers:\n\n```ts\nimport { pubSub } from \"./pubsub\";\n\nclass SampleResolver {\n  // ...\n  @Mutation(returns => Boolean)\n  async addNewComment(@Arg(\"comment\") input: CommentInput) {\n    const comment = this.commentsService.createNew(input);\n    await this.commentsRepository.save(comment);\n    // Trigger subscriptions topics\n    const payload: NotificationPayload = { message: input.content };\n    pubSub.publish(\"NOTIFICATIONS\", payload);\n    return true;\n  }\n}\n```\n\nAnd that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation.\n\n## Topic with dynamic ID\n\nThe idea of this feature is taken from the `@graphql-yoga/subscription` that is used under the hood.\nBasically, 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.:\n\n```ts\n@Resolver()\nclass NotificationResolver {\n  @Subscription({\n    topics: \"NOTIFICATIONS\",\n    topicId: ({ context }) => context.userId,\n  })\n  newNotification(@Root() { message }: NotificationPayload): Notification {\n    return { message, date: new Date() };\n  }\n}\n```\n\nThen in your mutation or services, you need to pass the topic id as the second parameter:\n\n```ts\npubSub.publish(\"NOTIFICATIONS\", userId, { id, message });\n```\n\n> Be aware that this feature must be supported by the pubsub system of your choice.\n> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscription`, the second argument might be treated as a payload, not dynamic topic id.\n\n## Using a custom PubSub system\n\nWhile TypeGraphQL uses the `@graphql-yoga/subscription` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`.\n\nIn fact, you can use any pubsub system you want, not only the `graphql-yoga` one.\nThe only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods.\n\nThis 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).\n\n## Creating a Subscription Server\n\nThe [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.\n\nHowever, 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:\n<https://www.apollographql.com/docs/apollo-server/data/subscriptions/#enabling-subscriptions>\n\n## Examples\n\nSee how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package.\n\nFor 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.4/examples/redis-subscriptions).\nHowever, 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.\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/unions.md",
    "content": "---\ntitle: Unions\nid: version-2.0.0-rc.4-unions\noriginal_id: unions\n---\n\nSometimes 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.\n\nRead more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).\n\n## Usage\n\nLet's start by creating the object types from the example above:\n\n```ts\n@ObjectType()\nclass Movie {\n  @Field()\n  name: string;\n\n  @Field()\n  rating: number;\n}\n```\n\n```ts\n@ObjectType()\nclass Actor {\n  @Field()\n  name: string;\n\n  @Field(type => Int)\n  age: number;\n}\n```\n\nNow 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:\n\n```ts\nimport { createUnionType } from \"type-graphql\";\n\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\", // Name of the GraphQL union\n  types: () => [Movie, Actor] as const, // function that returns tuple of object types classes\n});\n```\n\nThen we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation.\nNotice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations.\nFor TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`.\n\n```ts\n@Resolver()\nclass SearchResolver {\n  @Query(returns => [SearchResultUnion])\n  async search(@Arg(\"phrase\") phrase: string): Promise<Array<typeof SearchResultUnion>> {\n    const movies = await Movies.findAll(phrase);\n    const actors = await Actors.findAll(phrase);\n\n    return [...movies, ...actors];\n  }\n}\n```\n\n## Resolving Type\n\nBe 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.\n\nHowever, 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.:\n\n```ts\nconst SearchResultUnion = createUnionType({\n  name: \"SearchResult\",\n  types: () => [Movie, Actor] as const,\n  // Implementation of detecting returned object type\n  resolveType: value => {\n    if (\"rating\" in value) {\n      return Movie; // Return object type class (the one with `@ObjectType()`)\n    }\n    if (\"age\" in value) {\n      return \"Actor\"; // Or the schema name of the type as a string\n    }\n    return undefined;\n  },\n});\n```\n\n**Et Voilà!** We can now build the schema and make the example query 😉\n\n```graphql\nquery {\n  search(phrase: \"Holmes\") {\n    ... on Actor {\n      # Maybe Katie Holmes?\n      name\n      age\n    }\n    ... on Movie {\n      # For sure Sherlock Holmes!\n      name\n      rating\n    }\n  }\n}\n```\n\n## Examples\n\nMore advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/enums-and-unions).\n"
  },
  {
    "path": "website/versioned_docs/version-2.0.0-rc.4/validation.md",
    "content": "---\ntitle: Argument and Input validation\nsidebar_label: Validation\nid: version-2.0.0-rc.4-validation\noriginal_id: validation\n---\n\n## Scalars\n\nThe 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.\n\nThat's why TypeGraphQL has built-in support for argument and input validation.\nBy 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.\n\nWe can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section.\n\n## `class-validator`\n\n### How to use\n\nFirst, we need to install the `class-validator` package:\n\n```sh\nnpm install class-validator\n```\n\nThen we decorate the input/arguments class with the appropriate decorators from `class-validator`.\nSo we take this:\n\n```ts\n@InputType()\nexport class RecipeInput {\n  @Field()\n  title: string;\n\n  @Field({ nullable: true })\n  description?: string;\n}\n```\n\n...and turn it into this:\n\n```ts\nimport { MaxLength, Length } from \"class-validator\";\n\n@InputType()\nexport class RecipeInput {\n  @Field()\n  @MaxLength(30)\n  title: string;\n\n  @Field({ nullable: true })\n  @Length(30, 255)\n  description?: string;\n}\n```\n\nThen we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: true, // Enable 'class-validator' integration\n});\n```\n\nAnd that's it! 😉\n\nTypeGraphQL will automatically validate our inputs and arguments based on the definitions:\n\n```ts\n@Resolver(of => Recipe)\nexport class RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\") recipeInput: RecipeInput): Promise<Recipe> {\n    // 100% sure that the input is correct\n    console.assert(recipeInput.title.length <= 30);\n    console.assert(recipeInput.description.length >= 30);\n    console.assert(recipeInput.description.length <= 255);\n  }\n}\n```\n\nOf 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.\n\nThis feature is enabled by default. However, we can disable it if we must:\n\n```ts\nconst schema = await buildSchema({\n  resolvers: [RecipeResolver],\n  validate: false, // Disable automatic validation or pass the default config object\n});\n```\n\nAnd we can still enable it per resolver's argument if we need to:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(@Arg(\"input\", { validate: true }) recipeInput: RecipeInput) {\n    // ...\n  }\n}\n```\n\nThe `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed:\n\n```ts\nclass RecipeResolver {\n  @Mutation(returns => Recipe)\n  async addRecipe(\n    @Arg(\"input\", { validate: { groups: [\"admin\"] } })\n    recipeInput: RecipeInput,\n  ) {\n    // ...\n  }\n}\n```\n\nNote 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.\nSame goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema.\n\nGraphQL 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!\n\nHowever, 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.\n\n### Response to the Client\n\nWhen a client sends incorrect data to the server:\n\n```graphql\nmutation ValidationMutation {\n  addRecipe(\n    input: {\n      # Too long!\n      title: \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n    }\n  ) {\n    title\n    creationDate\n  }\n}\n```\n\nthe [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown.\n\nBy 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`:\n\n```json\n{\n  \"errors\": [\n    {\n      \"message\": \"Argument Validation Error\",\n      \"locations\": [\n        {\n          \"line\": 2,\n          \"column\": 3\n        }\n      ],\n      \"path\": [\"addRecipe\"],\n      \"extensions\": {\n        \"code\": \"INTERNAL_SERVER_ERROR\",\n        \"exception\": {\n          \"validationErrors\": [\n            {\n              \"target\": {\n                \"title\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\"\n              },\n              \"value\": \"Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\",\n              \"property\": \"title\",\n              \"children\": [],\n              \"constraints\": {\n                \"maxLength\": \"title must be shorter than or equal to 30 characters\"\n              }\n            }\n          ],\n          \"stacktrace\": [\n            \"Error: Argument Validation Error\",\n            \"    at Object.<anonymous> (/type-graphql/src/resolvers/validate-arg.ts:29:11)\",\n            \"    at Generator.throw (<anonymous>)\",\n            \"    at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)\",\n            \"    at processTicksAndRejections (internal/process/next_tick.js:81:5)\"\n          ]\n        }\n      }\n    }\n  ],\n  \"data\": null\n}\n```\n\nOf 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\"`).\n\n### Automatic Validation Example\n\nTo see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/automatic-validation).\n\n### Caveats\n\nEven 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`.\n\nAn 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`.\n\n## Custom validator\n\nWe can also use other libraries than `class-validator` together with TypeGraphQL.\n\nTo integrate it, all we need to do is to provide a custom function.\nIt receives three parameters:\n\n- `argValue` which is the injected value of `@Arg()` or `@Args()`\n- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`)\n- `resolverData` which holds the resolver execution context, described as generic type `ResolverData<TContext>`\n\nThis function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails.\nSo be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL.\n\nThen we provide this function as a `validateFn` option in `buildSchema`.\nExample using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful):\n\n```ts\nconst schema = await buildSchema({\n  // ...\n  validateFn: argValue => {\n    // Call joiful validate\n    const { error } = joiful.validate(argValue);\n    if (error) {\n      // Throw error on failed validation\n      throw error;\n    }\n  },\n});\n```\n\nThe `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.:\n\n```ts\n@Resolver()\nclass SampleResolver {\n  @Query()\n  sampleQuery(\n    @Arg(\"sampleArg\", {\n      validateFn: (argValue, argType) => {\n        // Do something here with arg value and type...\n      },\n    })\n    sampleArg: string,\n  ): string {\n    // ...\n  }\n}\n```\n\n> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation.\n\n### Custom Validation Example\n\nTo see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.4/examples/custom-validation).\n"
  },
  {
    "path": "website/versioned_sidebars/version-0.16.0-sidebars.json",
    "content": "{\n  \"version-0.16.0-docs\": {\n    \"Introduction\": [\"version-0.16.0-introduction\"],\n    \"Beginner guides\": [\n      \"version-0.16.0-getting-started\",\n      \"version-0.16.0-types-and-fields\",\n      \"version-0.16.0-resolvers\",\n      \"version-0.16.0-bootstrap\"\n    ],\n    \"Advanced guides\": [\n      \"version-0.16.0-scalars\",\n      \"version-0.16.0-enums\",\n      \"version-0.16.0-unions\",\n      \"version-0.16.0-subscriptions\",\n      \"version-0.16.0-interfaces-and-inheritance\"\n    ],\n    \"Features\": [\n      \"version-0.16.0-dependency-injection\",\n      \"version-0.16.0-authorization\",\n      \"version-0.16.0-validation\",\n      \"version-0.16.0-middlewares\",\n      \"version-0.16.0-complexity\"\n    ],\n    \"Others\": [\"version-0.16.0-emit-schema\", \"version-0.16.0-browser-usage\"]\n  },\n  \"version-0.16.0-examples\": {\n    \"Examples\": [\"version-0.16.0-examples\"]\n  },\n  \"version-0.16.0-others\": {\n    \"Others\": [\"version-0.16.0-faq\"]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-0.17.0-sidebars.json",
    "content": "{\n  \"version-0.17.0-docs\": {\n    \"Introduction\": [\"version-0.17.0-introduction\"],\n    \"Beginner guides\": [\n      \"version-0.17.0-installation\",\n      \"version-0.17.0-getting-started\",\n      \"version-0.17.0-types-and-fields\",\n      \"version-0.17.0-resolvers\",\n      \"version-0.17.0-bootstrap\"\n    ],\n    \"Advanced guides\": [\n      \"version-0.17.0-scalars\",\n      \"version-0.17.0-enums\",\n      \"version-0.17.0-unions\",\n      \"version-0.17.0-interfaces\",\n      \"version-0.17.0-subscriptions\"\n    ],\n    \"Features\": [\n      \"version-0.17.0-dependency-injection\",\n      \"version-0.17.0-authorization\",\n      \"version-0.17.0-validation\",\n      \"version-0.17.0-inheritance\",\n      \"version-0.17.0-generic-types\",\n      \"version-0.17.0-middlewares\",\n      \"version-0.17.0-complexity\"\n    ],\n    \"Others\": [\"version-0.17.0-emit-schema\", \"version-0.17.0-browser-usage\"]\n  },\n  \"version-0.17.0-examples\": {\n    \"Examples\": [\"version-0.17.0-examples\"]\n  },\n  \"version-0.17.0-others\": {\n    \"Others\": [\"version-0.17.0-faq\"]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-0.17.4-sidebars.json",
    "content": "{\n  \"version-0.17.4-docs\": {\n    \"Introduction\": [\"version-0.17.4-introduction\"],\n    \"Beginner guides\": [\n      \"version-0.17.4-installation\",\n      \"version-0.17.4-getting-started\",\n      \"version-0.17.4-types-and-fields\",\n      \"version-0.17.4-resolvers\",\n      \"version-0.17.4-bootstrap\"\n    ],\n    \"Advanced guides\": [\n      \"version-0.17.4-scalars\",\n      \"version-0.17.4-enums\",\n      \"version-0.17.4-unions\",\n      \"version-0.17.4-interfaces\",\n      \"version-0.17.4-subscriptions\"\n    ],\n    \"Features\": [\n      \"version-0.17.4-dependency-injection\",\n      \"version-0.17.4-authorization\",\n      \"version-0.17.4-validation\",\n      \"version-0.17.4-inheritance\",\n      \"version-0.17.4-generic-types\",\n      \"version-0.17.4-middlewares\",\n      \"version-0.17.4-custom-decorators\",\n      \"version-0.17.4-complexity\"\n    ],\n    \"Others\": [\"version-0.17.4-emit-schema\", \"version-0.17.4-browser-usage\"]\n  },\n  \"version-0.17.4-examples\": {\n    \"Examples\": [\"version-0.17.4-examples\"]\n  },\n  \"version-0.17.4-others\": {\n    \"Others\": [\"version-0.17.4-faq\"]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-1.0.0-sidebars.json",
    "content": "{\n  \"version-1.0.0-docs\": {\n    \"Introduction\": [\"version-1.0.0-introduction\"],\n    \"Beginner guides\": [\n      \"version-1.0.0-installation\",\n      \"version-1.0.0-getting-started\",\n      \"version-1.0.0-types-and-fields\",\n      \"version-1.0.0-resolvers\",\n      \"version-1.0.0-bootstrap\"\n    ],\n    \"Advanced guides\": [\n      \"version-1.0.0-scalars\",\n      \"version-1.0.0-enums\",\n      \"version-1.0.0-unions\",\n      \"version-1.0.0-interfaces\",\n      \"version-1.0.0-subscriptions\",\n      \"version-1.0.0-directives\",\n      \"version-1.0.0-extensions\"\n    ],\n    \"Features\": [\n      \"version-1.0.0-dependency-injection\",\n      \"version-1.0.0-authorization\",\n      \"version-1.0.0-validation\",\n      \"version-1.0.0-inheritance\",\n      \"version-1.0.0-generic-types\",\n      \"version-1.0.0-middlewares\",\n      \"version-1.0.0-custom-decorators\",\n      \"version-1.0.0-complexity\"\n    ],\n    \"Integrations\": [\"version-1.0.0-prisma\", \"version-1.0.0-nestjs\"],\n    \"Others\": [\n      \"version-1.0.0-emit-schema\",\n      \"version-1.0.0-performance\",\n      \"version-1.0.0-browser-usage\"\n    ]\n  },\n  \"version-1.0.0-examples\": {\n    \"Examples\": [\"version-1.0.0-examples\"]\n  },\n  \"version-1.0.0-others\": {\n    \"Others\": [\"version-1.0.0-faq\"]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-2.0.0-beta.3-sidebars.json",
    "content": "{\n  \"version-2.0.0-beta.3-docs\": {\n    \"Introduction\": [\n      \"version-2.0.0-beta.3-introduction\"\n    ],\n    \"Beginner guides\": [\n      \"version-2.0.0-beta.3-installation\",\n      \"version-2.0.0-beta.3-getting-started\",\n      \"version-2.0.0-beta.3-types-and-fields\",\n      \"version-2.0.0-beta.3-resolvers\",\n      \"version-2.0.0-beta.3-bootstrap\",\n      \"version-2.0.0-beta.3-esm\"\n    ],\n    \"Advanced guides\": [\n      \"version-2.0.0-beta.3-scalars\",\n      \"version-2.0.0-beta.3-enums\",\n      \"version-2.0.0-beta.3-unions\",\n      \"version-2.0.0-beta.3-interfaces\",\n      \"version-2.0.0-beta.3-subscriptions\",\n      \"version-2.0.0-beta.3-directives\",\n      \"version-2.0.0-beta.3-extensions\"\n    ],\n    \"Features\": [\n      \"version-2.0.0-beta.3-dependency-injection\",\n      \"version-2.0.0-beta.3-authorization\",\n      \"version-2.0.0-beta.3-validation\",\n      \"version-2.0.0-beta.3-inheritance\",\n      \"version-2.0.0-beta.3-generic-types\",\n      \"version-2.0.0-beta.3-middlewares\",\n      \"version-2.0.0-beta.3-custom-decorators\",\n      \"version-2.0.0-beta.3-complexity\"\n    ],\n    \"Integrations\": [\n      \"version-2.0.0-beta.3-prisma\",\n      \"version-2.0.0-beta.3-nestjs\"\n    ],\n    \"Others\": [\n      \"version-2.0.0-beta.3-emit-schema\",\n      \"version-2.0.0-beta.3-performance\",\n      \"version-2.0.0-beta.3-browser-usage\"\n    ]\n  },\n  \"version-2.0.0-beta.3-examples\": {\n    \"Examples\": [\n      \"version-2.0.0-beta.3-examples\"\n    ]\n  },\n  \"version-2.0.0-beta.3-others\": {\n    \"Others\": [\n      \"version-2.0.0-beta.3-faq\"\n    ]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-2.0.0-beta.4-sidebars.json",
    "content": "{\n  \"version-2.0.0-beta.4-docs\": {\n    \"Introduction\": [\n      \"version-2.0.0-beta.4-introduction\"\n    ],\n    \"Beginner guides\": [\n      \"version-2.0.0-beta.4-installation\",\n      \"version-2.0.0-beta.4-getting-started\",\n      \"version-2.0.0-beta.4-types-and-fields\",\n      \"version-2.0.0-beta.4-resolvers\",\n      \"version-2.0.0-beta.4-bootstrap\",\n      \"version-2.0.0-beta.4-esm\"\n    ],\n    \"Migration guide\": [\n      \"version-2.0.0-beta.4-migration-guide\"\n    ],\n    \"Advanced guides\": [\n      \"version-2.0.0-beta.4-scalars\",\n      \"version-2.0.0-beta.4-enums\",\n      \"version-2.0.0-beta.4-unions\",\n      \"version-2.0.0-beta.4-interfaces\",\n      \"version-2.0.0-beta.4-subscriptions\",\n      \"version-2.0.0-beta.4-directives\",\n      \"version-2.0.0-beta.4-extensions\"\n    ],\n    \"Features\": [\n      \"version-2.0.0-beta.4-dependency-injection\",\n      \"version-2.0.0-beta.4-authorization\",\n      \"version-2.0.0-beta.4-validation\",\n      \"version-2.0.0-beta.4-inheritance\",\n      \"version-2.0.0-beta.4-generic-types\",\n      \"version-2.0.0-beta.4-middlewares\",\n      \"version-2.0.0-beta.4-custom-decorators\",\n      \"version-2.0.0-beta.4-complexity\"\n    ],\n    \"Integrations\": [\n      \"version-2.0.0-beta.4-prisma\",\n      \"version-2.0.0-beta.4-nestjs\"\n    ],\n    \"Others\": [\n      \"version-2.0.0-beta.4-emit-schema\",\n      \"version-2.0.0-beta.4-performance\"\n    ],\n    \"Recipes\": [\n      \"version-2.0.0-beta.4-browser-usage\",\n      \"version-2.0.0-beta.4-aws-lambda\"\n    ]\n  },\n  \"version-2.0.0-beta.4-examples\": {\n    \"Examples\": [\n      \"version-2.0.0-beta.4-examples\"\n    ]\n  },\n  \"version-2.0.0-beta.4-others\": {\n    \"Others\": [\n      \"version-2.0.0-beta.4-faq\"\n    ]\n  }\n}\n"
  },
  {
    "path": "website/versioned_sidebars/version-2.0.0-rc.2-sidebars.json",
    "content": "{\n  \"version-2.0.0-rc.2-docs\": {\n    \"Introduction\": [\n      \"version-2.0.0-rc.2-introduction\"\n    ],\n    \"Beginner guides\": [\n      \"version-2.0.0-rc.2-installation\",\n      \"version-2.0.0-rc.2-getting-started\",\n      \"version-2.0.0-rc.2-types-and-fields\",\n      \"version-2.0.0-rc.2-resolvers\",\n      \"version-2.0.0-rc.2-bootstrap\",\n      \"version-2.0.0-rc.2-esm\"\n    ],\n    \"Migration guide\": [\n      \"version-2.0.0-rc.2-migration-guide\"\n    ],\n    \"Advanced guides\": [\n      \"version-2.0.0-rc.2-scalars\",\n      \"version-2.0.0-rc.2-enums\",\n      \"version-2.0.0-rc.2-unions\",\n      \"version-2.0.0-rc.2-interfaces\",\n      \"version-2.0.0-rc.2-subscriptions\",\n      \"version-2.0.0-rc.2-directives\",\n      \"version-2.0.0-rc.2-extensions\"\n    ],\n    \"Features\": [\n      \"version-2.0.0-rc.2-dependency-injection\",\n      \"version-2.0.0-rc.2-authorization\",\n      \"version-2.0.0-rc.2-validation\",\n      \"version-2.0.0-rc.2-inheritance\",\n      \"version-2.0.0-rc.2-generic-types\",\n      \"version-2.0.0-rc.2-middlewares\",\n      \"version-2.0.0-rc.2-custom-decorators\",\n      \"version-2.0.0-rc.2-complexity\"\n    ],\n    \"Integrations\": [\n      \"version-2.0.0-rc.2-prisma\",\n      \"version-2.0.0-rc.2-nestjs\"\n    ],\n    \"Others\": [\n      \"version-2.0.0-rc.2-emit-schema\",\n      \"version-2.0.0-rc.2-performance\"\n    ],\n    \"Recipes\": [\n      \"version-2.0.0-rc.2-browser-usage\",\n      \"version-2.0.0-rc.2-aws-lambda\",\n      \"version-2.0.0-rc.2-azure-functions\"\n    ]\n  },\n  \"version-2.0.0-rc.2-examples\": {\n    \"Examples\": [\n      \"version-2.0.0-rc.2-examples\"\n    ]\n  },\n  \"version-2.0.0-rc.2-others\": {\n    \"Others\": [\n      \"version-2.0.0-rc.2-faq\"\n    ]\n  }\n}\n"
  },
  {
    "path": "website/versions.json",
    "content": "[\n  \"2.0.0-rc.4\",\n  \"2.0.0-rc.3\",\n  \"2.0.0-rc.2\",\n  \"2.0.0-rc.1\",\n  \"2.0.0-beta.6\",\n  \"2.0.0-beta.4\",\n  \"2.0.0-beta.3\",\n  \"1.2.0-rc.1\",\n  \"1.1.1\",\n  \"1.1.0\",\n  \"1.0.0\",\n  \"0.17.6\",\n  \"0.17.5\",\n  \"0.17.4\",\n  \"0.17.3\",\n  \"0.17.2\",\n  \"0.17.1\",\n  \"0.17.0\",\n  \"0.16.0\"\n]\n"
  }
]