Code Monkey home page Code Monkey logo

typegraphql-nestjs's Introduction

typegraphql logo nest logo

TypeGraphQL NestJS Module

Basic integration of TypeGraphQL in NestJS.

Allows to use TypeGraphQL features while integrating with NestJS modules system and dependency injector.

Installation

First, you need to instal the typegraphql-nestjs module along with @nestjs/graphql:

npm i typegraphql-nestjs @nestjs/graphql

If you haven't installed it yet, it's time to add type-graphql into the project:

npm i type-graphql

How to use?

The typegraphql-nestjs package exports TypeGraphQLModule dynamic module, which is based on the official NestJS GraphQLModule. It exposes three static methods:

.forRoot()

The first one is TypeGraphQLModule.forRoot() which you should call on your root module, just like with the official GraphQLModule.

The only difference is that as its argument you can provide typical TypeGraphQL buildSchema options like emitSchemaFile or authChecker apart from the standard GqlModuleOptions from @nestjs/graphql like installSubscriptionHandlers or context:

import { Module } from "@nestjs/common";
import { TypeGraphQLModule } from "typegraphql-nestjs";

import RecipeModule from "./recipe/module";
import { authChecker } from "./auth";

@Module({
  imports: [
    TypeGraphQLModule.forRoot({
      driver: ApolloDriver,
      emitSchemaFile: true,
      authChecker,
      scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],
      context: ({ req }) => ({ currentUser: req.user }),
    }),
    RecipeModule,
  ],
})
export default class AppModule {}

Then, inside the imported modules (like RecipeModule) you just need to register the resolvers classes in the module providers array:

import { Module } from "@nestjs/common";

import RecipeResolver from "./resolver";
import RecipeService from "./service";

@Module({
  providers: [RecipeResolver, RecipeService],
})
export default class RecipeModule {}

And that's it! ๐Ÿ˜

Notice that the resolvers classes are automatically inferred from your submodules providers array, so you don't need to specify resolvers property from TypeGraphQL buildSchema options inside TypeGraphQLModule.forRoot().

.forFeature()

In case of need to provide orphanedTypes setting, you should use TypeGraphQLModule.forFeature(). The recommended place for that is in the module where the orphaned type (like SuperRecipe) belongs:

import { Module } from "@nestjs/common";
import { TypeGraphQLModule } from "typegraphql-nestjs";

import RecipeResolver from "./resolver";
import RecipeService from "./service";
import { SuperRecipe } from "./types";

@Module({
  imports: [
    TypeGraphQLModule.forFeature({
      orphanedTypes: [SuperRecipe],
    }),
  ],
  providers: [RecipeResolver, RecipeService],
})
export default class RecipeModule {}

Using .forFeature() ensures proper schemas isolation and automatically supply orphanedTypes option for underlying buildSchema from TypeGraphQL - again, there's no need to provide it manually in .forRoot() options.

.forRootAsync()

If you need to access some services to construct the TypeGraphQLModule options, you might be interested in the TypeGraphQLModule.forRootAsync() method. It allows you to define your own useFactory implementation where you have injected services from imports option.

Example of using the config service to generate TypeGraphQLModule options:

@Module({
  imports: [
    ConfigModule,
    RecipeModule,
    TypeGraphQLModule.forRootAsync({
      driver: ApolloDriver,
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => ({
        cors: true,
        debug: config.isDevelopmentMode,
        playground: !config.isDevelopmentMode,
        scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],
        emitSchemaFile:
          config.isDevelopmentMode && path.resolve(__dirname, "schema.graphql"),
      }),
    }),
  ],
})
export default class AppModule {}

Apollo Federation

typegraphql-nestjs has also support for Apollo Federation.

However, Apollo Federation requires building a federated GraphQL schema, hence you need to adjust your code a bit.

The usage is really similar to the basic case - the only difference is that in TypeGraphQLModule.forFeature() method you can provide a referenceResolvers option object, which is needed in some cases of Apollo Federation:

function resolveUserReference(
  reference: Pick<User, "id">,
): Promise<User | undefined> {
  return db.users.find({ id: reference.id });
}

@Module({
  imports: [
    TypeGraphQLModule.forFeature({
      orphanedTypes: [User],
      referenceResolvers: {
        User: {
          __resolveReference: resolveUserReference,
        },
      },
    }),
  ],
  providers: [AccountsResolver],
})
export default class AccountModule {}

For the .forRoot() method there's no differences - just need to provide driver: ApolloFederationDriver option in order to build a subgraph schema, same as with GraphQLModule from @nestjs/graphql described in the NestJS docs. However, you also need to explicitly setup federation version, by using federationVersion option:

@Module({
  imports: [
    TypeGraphQLModule.forRoot({
      driver: ApolloFederationDriver,
      federationVersion: 2,
    }),
    AccountModule,
  ],
})
export default class AppModule {}

Then, for exposing the federated schema using Apollo Gateway, you should use the standard NestJS ApolloGatewayDriver solution.

Caveats

While this integration provides a way to use TypeGraphQL with NestJS modules and dependency injector, for now it doesn't support other NestJS features like guards, interceptors, filters and pipes.

To achieve the same goals, you can use standard TypeGraphQL equivalents - middlewares, custom decorators, built-in authorization and validation.

Moreover, with typegraphql-nestjs you can also take advantage of additional features (comparing to @nestjs/graphql) like inline field resolvers, Prisma 2 integration or up-to-date capabilities like deprecating input fields and args (thanks to always synced with latests graphql-js).

Examples

You can see some examples of the integration in this repo:

  1. Basics

    Basics of the integration, like TypeGraphQLModule.forRoot usage

  2. Multiple Servers

    Advanced usage of multiple schemas inside single NestJS app - demonstration of schema isolation in modules and TypeGraphQLModule.forFeature usage

  3. Request scoped dependencies

    Usage of request scoped dependencies - retrieving fresh instances of resolver and service classes on every request (query/mutation)

  4. Middlewares

    Usage of class-based middlewares - modules, providers and schema options

  5. Apollo Federation (OLD)

    Showcase of the legacy Apollo Federation approach

  6. Apollo Federation V2

    Showcase of the new Apollo Federation V2 approach

Most of them you can run by using ts-node, like npx ts-node ./examples/1-basics/index.ts.

All examples folders contain a query.graphql file with some examples operations you can perform on the GraphQL servers.

Security contact information

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

typegraphql-nestjs's People

Contributors

clayrisser avatar devniel avatar michallytek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

typegraphql-nestjs's Issues

Dependency tree error

Hi,
I just tried installing typegraphql-nestjs after a fresh install of a nestjs app and I am getting a npm ERR! ERESOLVE unable to resolve dependency tree error:

npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: undefined@undefined
npm ERR! Found: [email protected]
npm ERR! node_modules/graphql
npm ERR!   peer graphql@"^16.5.0" from @apollo/[email protected]
npm ERR!   node_modules/@apollo/gateway
npm ERR!     peer @apollo/gateway@"^2.2.3" from [email protected]
npm ERR!     node_modules/typegraphql-nestjs
npm ERR!       typegraphql-nestjs@"*" from the root project
npm ERR!   peer graphql@"^16.5.0" from @apollo/[email protected]
npm ERR!   node_modules/@apollo/subgraph
npm ERR!     peer @apollo/subgraph@"^2.2.3" from [email protected]
npm ERR!     node_modules/typegraphql-nestjs
npm ERR!       typegraphql-nestjs@"*" from the root project
npm ERR!     peerOptional @apollo/subgraph@"^0.1.5 || ^0.3.0 || ^0.4.0 || ^2.0.0" from @nestjs/[email protected]
npm ERR!     node_modules/@nestjs/graphql
npm ERR!       peer @nestjs/graphql@"^10.1.7" from [email protected]
npm ERR!       node_modules/typegraphql-nestjs
npm ERR!         typegraphql-nestjs@"*" from the root project
npm ERR!   2 more (@nestjs/graphql, graphql-tag)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer graphql@"^15.3.0" from [email protected]
npm ERR! node_modules/type-graphql
npm ERR!   peer type-graphql@"^1.1.1 || 2.0.0-beta.1" from [email protected]
npm ERR!   node_modules/typegraphql-nestjs
npm ERR!     typegraphql-nestjs@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Is there a workaround to get this working?

Thanks,

@Inject(CONTEXT) is undefined

It seems that @Inject(CONTEXT) is not working with typegraphql-nestjs the way it does for @nestjs/graphql.

I am trying to do something like this:

import { Inject, Injectable } from "@nestjs/common";
import { CONTEXT } from "@nestjs/graphql";
import { Recipe } from "./types";

@Injectable()
export default class RecipeService {
  private readonly recipes: Recipe[] = [];

  constructor(@Inject(CONTEXT) context) {
    console.log('Request Headers:', context?.req?.headers);
  } 
}

With an app module that looks like this:

import { ApolloDriver } from "@nestjs/apollo";
import { Module } from "@nestjs/common";
import { TypeGraphQLModule } from "typegraphql-nestjs";

import RecipeModule from "./recipe/module";

@Module({
  imports: [
    TypeGraphQLModule.forRoot({
      driver: ApolloDriver,
      emitSchemaFile: true,
      context: ({ req, res }) => {
        return { req, res };
      }
    }),
    RecipeModule,
  ],
})
export default class AppModule {}

However, context is just undefined. A similar example using @nestjs/graphql however does work, mostly following https://docs.nestjs.com/fundamentals/injection-scopes#request-provider.

I have not found anything in the docs that says this should not work or how to achieve this differently, so if this is expected or just works differently please let me know. I think this may be a similar issue as discussed in #22, but it was never reproduced or fixed.

Initially I was not sure myself where the issue comes from, so I have created a reproduction with both typegraphql-nestjs and @nestjs/graphql here: https://github.com/ahilke/typegraphql-nestjs-inject-context.

Thank you for your support!

Nest v8.0.0

Hi @MichalLytek ! How are you?

When i want to use typegraphql-nestjs in a new project nestjs 8.0.0 throws me dependency peer error

npm ERR! Could not resolve dependency: npm ERR! peer @nestjs/common@"^7.6.13" from [email protected]

Possible solution update your package.json
"@nestjs/common": "^7.6.13" to "@nestjs/common": "^8.0.0",
"@nestjs/core": "^7.6.13" to "@nestjs/core": "^8.0.0",
"@nestjs/graphql": "^7.9.10" to "@nestjs/graphql": "^8.0.2"

Unable to change base path for ws

Discussed in #43

Originally posted by lcanavesio October 21, 2022
Hi @MichalLytek . i Use @typegraphql-nestjs 0.4.1
What is the correct way to change the path for ws? When i change my path to other ws connection fail

Ok: '/graphql'
TypeGraphQLModule.forRoot({ emitSchemaFile: true, installSubscriptionHandlers: true, path: '/graphql' })

Failed: '/apiv2/graphql'
TypeGraphQLModule.forRoot({ emitSchemaFile: true, installSubscriptionHandlers: true, path: '/apiv2/graphql' })

In browser see
WebSocket connection to 'ws://10.101.125.116:3008/apiv2/graphql' failed:

Getting error "Error: Error: spawn typegraphql-prisma ENOENT" on `npx prisma generate`

I'm getting error typegraphql-prisma enoent while running prisma generate

My package.json file:

{
  "name": "prisma-nest-starter-v1",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/bull": "^0.3.1",
    "@nestjs/common": "^7.5.1",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.5.1",
    "@nestjs/graphql": "^7.9.10",
    "@nestjs/jwt": "^7.2.0",
    "@nestjs/passport": "^7.1.5",
    "@nestjs/platform-express": "^7.5.1",
    "@prisma/client": "^2.17.0",
    "apollo-server-express": "^2.21.0",
    "bcrypt": "^5.0.1",
    "bull": "^3.20.1",
    "cache-manager": "^3.4.0",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "express-rate-limit": "^5.2.6",
    "graphql": "^15.5.0",
    "luxon": "^1.26.0",
    "otplib": "^12.0.1",
    "passport": "^0.4.1",
    "passport-jwt": "^4.0.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.3",
    "type-graphql": "^1.1.1"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.1",
    "@nestjs/schematics": "^7.1.3",
    "@nestjs/testing": "^7.5.1",
    "@types/bull": "^3.15.0",
    "@types/cache-manager": "^3.4.0",
    "@types/express": "^4.17.8",
    "@types/jest": "^26.0.15",
    "@types/luxon": "^1.26.2",
    "@types/node": "^14.14.6",
    "@types/passport-jwt": "^3.0.5",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.6.1",
    "@typescript-eslint/parser": "^4.6.1",
    "eslint": "^7.12.1",
    "eslint-config-prettier": "7.2.0",
    "eslint-plugin-prettier": "^3.1.4",
    "jest": "^26.6.3",
    "prettier": "^2.1.2",
    "prisma": "^2.17.0",
    "supertest": "^6.0.0",
    "ts-jest": "^26.4.3",
    "ts-loader": "^8.0.8",
    "ts-node": "^9.0.0",
    "tsconfig-paths": "^3.9.0",
    "typegraphql-nestjs": "^0.3.1",
    "typescript": "^4.0.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

prisma schema:

generator typegraphql {
  provider = "typegraphql-prisma"
  output   = "../prisma/generated/type-graphql"
}

npx prisma generate debug logs:

Environment variables loaded from .env
  prisma:engines using NAPI: false +0ms
  prisma:engines binaries to download query-engine, migration-engine, introspection-engine, prisma-fmt +2ms
Prisma schema loaded from prisma\schema.prisma
  prisma:download copying C:\Users\dell\Documents\Nest\Projects\nest-prisma-starter-v1\node_modules\.cache\prisma\master\c1455d0b443d66b0d9db9bcb1bb9ee0d5bbc511d\windows\query-engine to C:\Users\dell\AppData\Roaming\npm-cache\_npx\10468\node_modules\prisma\query-engine-windows.exe +0ms
{
  prismaClientDir: 'C:\\Users\\dell\\Documents\\Nest\\Projects\\nest-prisma-starter-v1\\node_modules\\@prisma\\client'
}
  prisma:GeneratorProcess 'typegraphql-prisma' is not recognized as an internal or external command, +0ms
  prisma:GeneratorProcess operable program or batch file. +1ms
  prisma:GeneratorProcess 2021-03-26T05:40:18.754Z prisma:client:generator requiredEngine: queryEngine +591ms

I'm not sure if this is a bug or something messed up on my system. Any help would be appreciated.

Cannot find module 'type-graphql'

I'm trying to add typegraphql-nestjs to an nx monorepo.

After running nx s api, the command failed with the following stack trace:

Require stack:
  - D:\dev\web\apps\crm\node_modules\typegraphql-nestjs\dist\typegraphql-options.factory.js
  - D:\dev\web\apps\crm\node_modules\typegraphql-nestjs\dist\typegraphql.module.js
  - D:\dev\web\apps\crm\node_modules\typegraphql-nestjs\dist\index.js
  - D:\dev\web\apps\crm\dist\apps\api\main.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:966:15)
    at Function.Module._load (internal/modules/cjs/loader.js:842:27)
    at Module.require (internal/modules/cjs/loader.js:1026:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (D:\dev\web\apps\crm\node_modules\typegraphql-nestjs\dist\typegraphql-options.factory.js:6:24)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Module.require (internal/modules/cjs/loader.js:1026:19)

Looks like the type-graphql isn't installed despite the existence in package.json as a devDependency.

app.module.ts

import { AuthModule } from '@crm/api/core/auth';
import { ExpertModule } from '@crm/api/expert';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';
import { TypeGraphQLModule } from 'typegraphql-nestjs';

@Module({
  imports: [
    AuthModule,
    ExpertModule,
    GraphQLModule.forRoot({
      autoSchemaFile: join(process.cwd(), 'schema.graphql'),
      installSubscriptionHandlers: true,
      debug: true,
      playground: true,
    }),
    TypeGraphQLModule.forRoot({
      dateScalarMode: 'timestamp',
      emitSchemaFile: true,
      validate: false,
      context: ({ req }) => ({ user: req.user }),
    }),
  ],
})
export class AppModule {}

package.json

{
"dependencies": {
    "@angular/animations": "^10.0.11",
    "@angular/common": "^10.0.11",
    "@angular/compiler": "^10.0.11",
    "@angular/core": "^10.0.11",
    "@angular/forms": "^10.0.11",
    "@angular/platform-browser": "^10.0.11",
    "@angular/platform-browser-dynamic": "^10.0.11",
    "@angular/router": "^10.0.11",
    "@nestjs/common": "^7.4.2",
    "@nestjs/core": "^7.4.2",
    "@nestjs/graphql": "^7.6.0",
    "@nestjs/jwt": "^7.1.0",
    "@nestjs/passport": "^7.1.0",
    "@nestjs/platform-express": "^7.4.2",
    "@nrwl/angular": "^10.0.13",
    "@prisma/client": "^2.5.1",
    "apollo-server-express": "^2.16.1",
    "graphql": "^15.3.0",
    "graphql-subscriptions": "^1.1.0",
    "graphql-tools": "^6.0.18",
    "passport": "^0.4.1",
    "passport-jwt": "^4.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "~6.6.2",
    "typegraphql-nestjs": "^0.2.2",
    "zone.js": "^0.10.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1000.6",
    "@angular/cli": "~10.0.6",
    "@angular/compiler-cli": "^10.0.11",
    "@angular/language-service": "^10.0.11",
    "@commitlint/cli": "^9.1.2",
    "@commitlint/config-conventional": "^9.1.2",
    "@nestjs/schematics": "^7.0.1",
    "@nestjs/testing": "^7.4.2",
    "@ngneat/spectator": "^5.13.0",
    "@nrwl/cypress": "10.0.13",
    "@nrwl/jest": "10.0.13",
    "@nrwl/nest": "10.0.13",
    "@nrwl/node": "10.0.13",
    "@nrwl/workspace": "10.0.13",
    "@prisma/cli": "^2.5.1",
    "@types/jest": "26.0.10",
    "@types/node": "~14.6.0",
    "@types/passport-jwt": "^3.0.3",
    "codelyzer": "~6.0.0",
    "cypress": "^5.0.0",
    "dotenv": "8.2.0",
    "eslint": "7.7.0",
    "husky": "^4.2.5",
    "jest": "26.4.1",
    "jest-preset-angular": "8.1.3",
    "prettier": "2.0.5",
    "ts-jest": "26.2.0",
    "ts-node": "~8.10.2",
    "tslint": "~6.1.3",
    "typescript": "~3.9.7"
  }
}

I've resolved the issue by installing type-graphql manually. Hope it'll be fixed in the future releases.

Nest can't resolve dependencies in the forRootAsync inject array

Hello. I'm using the new forRootAsync method to inject some modules, but it's now working as intended.

[Nest] 50966   - 09/28/2020, 7:25:27 PM   [NestFactory] Starting Nest application...
[Nest] 50966   - 09/28/2020, 7:25:27 PM   [InstanceLoader] AppModule dependencies initialized +42ms
[Nest] 50966   - 09/28/2020, 7:25:27 PM   [ExceptionHandler] Nest can't resolve dependencies of the TYPEGRAPHQL_ROOT_MODULE_OPTIONS (PrismaService, ?). Please make sure that the argument ConfigService at index [1] is available in the GraphQLModule context.

Potential solutions:
- If ConfigService is a provider, is it part of the current GraphQLModule?
- If ConfigService is exported from a separate @Module, is that module imported within GraphQLModule?
  @Module({
    imports: [ /* the Module containing ConfigService */ ]
  })
 +1ms
Error: Nest can't resolve dependencies of the TYPEGRAPHQL_ROOT_MODULE_OPTIONS (PrismaService, ?). Please make sure that the argument ConfigService at index [1] is available in the GraphQLModule context.

Potential solutions:
- If ConfigService is a provider, is it part of the current GraphQLModule?
- If ConfigService is exported from a separate @Module, is that module imported within GraphQLModule?
  @Module({
    imports: [ /* the Module containing ConfigService */ ]
  })

    at Injector.lookupComponentInParentModules (/home/app/node_modules/@nestjs/core/injector/injector.js:192:19)
    at async Injector.resolveComponentInstance (/home/app/node_modules/@nestjs/core/injector/injector.js:148:33)
    at async resolveParam (/home/app/node_modules/@nestjs/core/injector/injector.js:102:38)
    at async Promise.all (index 1)
    at async Injector.resolveConstructorParams (/home/app/node_modules/@nestjs/core/injector/injector.js:117:27)
    at async Injector.loadInstance (/home/app/node_modules/@nestjs/core/injector/injector.js:81:9)
    at async Injector.loadProvider (/home/app/node_modules/@nestjs/core/injector/injector.js:38:9)
    at async Promise.all (index 15)
    at async InstanceLoader.createInstancesOfProviders (/home/app/node_modules/@nestjs/core/injector/instance-loader.js:43:9)
    at async /home/app/node_modules/@nestjs/core/injector/instance-loader.js:28:13

the PrismaService works by making the PrismaModule global, this is my AppModule:

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConfigModule.forFeature(commonConfig),
    PrismaModule,
    TypeGraphQLModule.forRootAsync({
      inject: [PrismaService, ConfigService],
      useFactory: (prisma: PrismaService, config: ConfigService) => ({
        authChecker: typegraphQLAuthChecker,
        context: graphqlContext(prisma),
        emitSchemaFile: config.get('NODE_ENV') === 'development',
      }),
    }),
  ],
})
export default class AppModule {}

seems like the underlying GraphQLModules isn't receiving the injected modules, but I'm not a big expert of Nest's inner workings.

Am I missing something?
Thank you for your attention

Cannot upload file: POST body missing, invalid Content-Type, or JSON object has no keys.

Problem

Hi @MichalLytek ,
I tried to make a GraphQL endpoint which accepts a text file in a NestJS app. However, I got the following error when I actually uploaded a text file to the endpoint via Altair:

"POST body missing, invalid Content-Type, or JSON object has no keys."

I'd like to solve this problem. If you shed some lights on it, I would really appreciate it.
(And I'm sorry in advance if I overlook something obvious)

Expected behavior

It's suppose to return the content of text file.

How to reproduce

The query I sent from Altair is the following:

mutation uploadFile($file: Upload!){
  uploadFile(file: $file){
    message
  }
}

I sent the above query, setting Content-type header to application/octet-stream.
When I set it to application/json, the error message changed:

{
  "statusCode": 400,
  "message": "Unexpected token - in JSON at position 0",
  "error": "Bad Request"
}

The resolver I made was the following:

import { Query, Resolver, Mutation, Args} from 'type-graphql';
import { UploadResponse, UploadInputArgs } from './types';
import { Readable } from 'stream';

@Resolver()
// you have to make at lease 1 query in a NestJS app
export class UploadResolver {
  @Query((returns)=>UploadResponse)
  getHello(): UploadResponse{
    return {
      message: 'hello'
    }
  }
// this endpoint does not work
  @Mutation((returns)=>UploadResponse)
  async importFile(
    @Args() args: UploadInputArgs
  ): Promise<any>{
    const file = await args.file
    const {createReadStream} = file
    const buffer = await this.streamToBuffer(createReadStream())
    return {
      message:buffer.toString()
    };
  }
  async streamToBuffer(stream: Readable): Promise<Buffer> {
    const buffer: Uint8Array[] = [];
    return new Promise((resolve, reject) =>
      stream
        .on('error', (error) => reject(error))
        .on('data', (data) => buffer.push(data))
        .on('end', () => resolve(Buffer.concat(buffer))),
    );
  }
}

The content of type.ts is the following.

import { ObjectType, Field, ArgsType } from "type-graphql";
import { GraphQLUpload } from "graphql-upload-minimal";
import { Readable } from 'stream';

@ObjectType()
export class UploadResponse {
  @Field(() => String)
  message!: String;
}

@ArgsType()
export class UploadInputArgs{
  @Field(() => GraphQLUpload)
  file!: Promise<Upload>;
}

class Upload{
  fieldName: string;
  filename: string;
  mimetype: string;
  encoding: string;
  createReadStream: ()=> Readable;
}

The whole (super small) repository is the following, for what it's worth.
nestjs-typegraphql-upload

What I tried to solve the problem

I made it sure that I could upload a file to a endpoint, if I use @nestjs/graphql instead of type-graphql. So I think it's due to type-graphql or typegraphql-nestjs.

Environment

I use M1 macbook and node v16.14.0, run the app in local(without using Docker).
The whole dependencies in package.json is the following:

  "dependencies": {
    "@apollo/subgraph": "^2.3.2",
    "@nestjs/apollo": "^10.2.0",
    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/graphql": "^10.2.0",
    "@nestjs/platform-express": "^9.0.0",
    "apollo-server-core": "^3.11.1",
    "apollo-server-express": "^3.11.1",
    "graphql": "^16.6.0",
    "graphql-upload-minimal": "^1.5.4",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.2.0",
    "type-graphql": "2.0.0-beta.1",
    "typegraphql-nestjs": "^0.5.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.0.0",
    "@nestjs/schematics": "^9.0.0",
    "@nestjs/testing": "^9.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "29.2.4",
    "@types/node": "18.11.18",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "29.3.1",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "29.0.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.1.1",
    "typescript": "^4.7.4"
  },

Problem with scoped providers

When I try to use @Injectable({ scope: Scope.REQUEST }) in my resolver I got the following error RecipeResolver is marked as a scoped provider. Request and transient-scoped providers can't be used in combination with "get()" method. Please, use "resolve()" instead.

The error point to this line:
https://github.com/MichalLytek/typegraphql-nestjs/blob/master/src/typegraphql-options.factory.ts#L58

It looks like for scoped providers we need to use resolve() instead of get().
https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers

Bug: impossible to run without conflict with peerDeps

These are peerDeps for typegraphql-nestj:

"peerDependencies": {
    "@apollo/federation": "^0.29.0",
    "@apollo/gateway": "^0.38.0",
    "@nestjs/common": "^8.0.6",
    "@nestjs/core": "^8.0.6",
    "@nestjs/graphql": "^8.0.2",
    "apollo-graphql": "^0.9.3",
    "graphql-tag": "^2.12.5",
    "type-graphql": "^1.1.1"
  }

I installed them. Notice this:

    "@apollo/federation": "^0.29.0",
    "@apollo/gateway": "^0.38.0",

But @nestjs/graphql requires these:

@nestjs/graphql 8.0.2
  โ”œโ”€โ”€ โœ• unmet peer @apollo/gateway@"^0.29.0 || ^0.32.0 || ^0.33.0": found 0.38.2
  โ””โ”€โ”€ โœ• unmet peer @apollo/federation@"^0.22.0 || ^0.25.2 || ^0.26.0": found 0.29.1

So basically there is no way to run typegraphql-nestjs without conflict with dependencies.

Is there some workaround for it? Thanks in advance!
@MichalLytek

Support for NestJS v10 and @nestjs/graphql v12

Currently, when trying to install this lib a new nest v10 app created via nest new, I get resolution issues:

code ERESOLVE
ERESOLVE unable to resolve dependency tree

While resolving: [email protected]
Found: @nestjs/[email protected]
node_modules/@nestjs/common
  @nestjs/common@"^10.0.3" from [email protected]
  backend
    [email protected]
    node_modules/backend
      workspace backend from the root project

Could not resolve dependency:
peer @nestjs/common@"^9.2.1" from [email protected]
node_modules/typegraphql-nestjs
  typegraphql-nestjs@"0.5.0" from [email protected]
  backend
    [email protected]
    node_modules/backend
      workspace backend from the root project

Fix the upstream dependency conflict, or retry
this command with --force, or --legacy-peer-deps
to accept an incorrect (and potentially broken) dependency resolution.

After forcing resolution with npm i --legacy-peer-deps I had to add @apollo/subgraph to my package.json deps (And graphql-fields and graphql-scalars as well for typegraphql-prisma)
That let me to get my app to start and emit GraphQL schema definitions as expected

Middleware causes error: Cannot read property 'isDependencyTreeStatic' of undefined

Hello, I want to use a Middleware class (that manages if a field is returned or not based on if the customer has an active premium subscription or not).

export class PremiumFeature implements MiddlewareInterface {
  constructor() {}

  async use({ context, info }: ResolverData, next: NextFn) {
    return next();
  }
}

for certain fields eg:

@ObjectType()
@InputType('BusinessInput')
@Entity()
export class Business extends StandardEntity {

  @UseMiddleware(PremiumFeature)
  @Field(field => [Card], { nullable: true })
  @OneToMany(
    () => Card,
    card => card.business,
  )
  public cards: Card[];
}

A sample request:

query business($id: Int!) {
  business(id: $id) {
    id
    cards{id}
  }
}

returns the following response with the error:

{
  "errors": [
    {
      "message": "Cannot read property 'isDependencyTreeStatic' of undefined",
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ],
      "path": [
        "business",
        "cards"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "TypeError: Cannot read property 'isDependencyTreeStatic' of undefined",
            "    at Object.get (/media/jim/Daten/projets/place_to_be/code/api/node_modules/typegraphql-nestjs/dist/typegraphql-options.factory.js:42:42)",
            "    at IOCContainer.getInstance (/media/jim/Daten/projets/place_to_be/code/api/node_modules/type-graphql/dist/utils/container.js:39:26)",
            "    at dispatchHandler (/media/jim/Daten/projets/place_to_be/code/api/node_modules/type-graphql/dist/resolvers/helpers.js:74:65)",
            "    at Object.applyMiddlewares (/media/jim/Daten/projets/place_to_be/code/api/node_modules/type-graphql/dist/resolvers/helpers.js:88:12)",
            "    at /media/jim/Daten/projets/place_to_be/code/api/node_modules/type-graphql/dist/resolvers/create.js:75:26",
            "    at field.resolve (/media/jim/Daten/projets/place_to_be/code/api/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)",
            "    at resolveField (/media/jim/Daten/projets/place_to_be/code/api/node_modules/graphql/execution/execute.js:464:18)",
            "    at executeFields (/media/jim/Daten/projets/place_to_be/code/api/node_modules/graphql/execution/execute.js:292:18)",
            "    at collectAndExecuteSubfields (/media/jim/Daten/projets/place_to_be/code/api/node_modules/graphql/execution/execute.js:748:10)",
            "    at completeObjectValue (/media/jim/Daten/projets/place_to_be/code/api/node_modules/graphql/execution/execute.js:738:10)"
          ]
        }
      }
    }
  ],
  "data": {
    "business": {
      "id": 59,
      "cards": null
    }
  }
}

The resolver class is using resolver inheritance, it contains this function:

@Authorized()
  @Query(() => Business, { name: 'business' })
  protected async getOne(@Arg('id', () => Int) id: number) {
    const result =  await this.businessService.get(id, {
      relations: [
        'openingHours',
        'tags',
        'tags.parentTag',
        'tags.childTags',
        'headerImages',
        'cards'
      ],
    });
    return result;
  }

I'd be happy to know what I can do to resolve this issue.
Kind regards.

Not sure how to get subscriptions server working

I am trying to get subscriptions going with this package, but there seems to be something off or missing.
This is my Module instance:

TypeGraphQLModule.forRootAsync({
      imports: [AuthModule, DynamicRedisModule],
      inject: [CookieStrategy, RedisService],
      useFactory: async (cookieStrategy: CookieStrategy, redisService: RedisService) => {
        return {
          validate: true,
          dateScalarMode: 'timestamp',
          playground: false,
          authChecker: cookieAuthChecker,
          path: '/',
          emitSchemaFile: true,
          uploads: false,
          globalMiddlewares: [GqlAuthGuard(), ReplaceMe()],
          context: async ({ request }): Promise<GraphQLContext> => ({
            prisma,
            user: await cookieStrategy.validate(request),
          }),
          cors: {
            origin: [/* urls... */],
            credentials: true,
          },
          pubSub: new RedisPubSub({
            publisher: redisService.getClient('publisher'),
            subscriber: redisService.getClient('subscriber'),
          }),
          installSubscriptionHandlers: true,
        };
      },
    }),

Starting up the server throws the following error:

(node:6923) UnhandledPromiseRejectionWarning: TypeError: this.apolloServer.installSubscriptionHandlers is not a function
    at GraphQLModule.<anonymous> (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/graphql/dist/graphql.module.js:97:35)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/graphql/node_modules/tslib/tslib.js:111:62)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

Although the nestjs docs state that installSubscriptionHandlers is a boolean: https://docs.nestjs.com/graphql/subscriptions#enable-subscriptions

I guess I have to pass a function but I don't know which one. Can you help out here?

Access PubSub in middleware

Hello, i am trying to access pubSub in middleware but cannot make it work. In documentation, I also did not find anything about it.
Is it possible to access pubSub inside of middleware?
Here is my code

@Injectable()
export class LogAccess implements MiddlewareInterface {
  constructor(@PubSub() private pubSub: PubSubEngine) {}

  async use(data: ResolverData, next: NextFn): Promise<any> {
    console.log({ pubSubInMiddleware: this.pubSub });
    console.log('Middleware');
    return next();
  }
}

@Resolver(String)
class CustomUserResolver {
  @Query((returns) => String, { nullable: true })
  @UseMiddleware(LogAccess)
  async bestUser(@Ctx() { prisma }: Context, @PubSub() pubSub: PubSubEngine) {
    // console.log({ pubSub });
    return 'You are the best of the best!!:)))';
  }
}

@Module({
  imports: [
    // use the TypeGraphQLModule to expose Prisma by GraphQL
    TypeGraphQLModule.forRoot({
      playground: true,
      introspection: true,
      emitSchemaFile,
      validate: false,
      context: () => ({ prisma }),
      globalMiddlewares: [LogAccess],
    }),
  ],
  controllers: [],
  providers: [CustomUserResolver, LogAccess, PubSubEngine as any],
})
export class AppModule {}

I am trying to use PubSubEngine, but since it is an abstract class, in middleware it is just an empty object :(

Support apollo/[email protected]

getting the following errors:

npm i [email protected]
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: @apollo/[email protected]
npm ERR! node_modules/@apollo/federation
npm ERR!   @apollo/federation@"^0.33.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @apollo/federation@"^0.29.0" from [email protected]
npm ERR! node_modules/typegraphql-nestjs
npm ERR!   typegraphql-nestjs@"0.4.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/sgentile/.npm/eresolve-report.txt for a full report.

If I switch to 0.29, then it wants "@nestjs/graphql": "^8.0.2", but then it requires Conflicting peer dependency: [email protected] so it cascades down etc...

These are the defaults right with latest NestJS:

"dependencies": {
        "@apollo/federation": "^0.33.0",
        "@nestjs/common": "^8.0.0",
        "@nestjs/config": "^1.0.1",
        "@nestjs/core": "^8.0.0",
        "@nestjs/graphql": "^9.0.5",
        "@nestjs/platform-express": "^8.0.0",
        "@nestjs/swagger": "^5.1.0",
        "@nestjs/terminus": "^8.0.1",
        "@prisma/client": "^3.1.1",
        "apollo-server-express": "^3.3.0",
        "graphql": "^15.6.0",
        "reflect-metadata": "^0.1.13",
        "rimraf": "^3.0.2",
        "rxjs": "^7.2.0",
        "ts-morph": "^12.0.0"
    },

Support for @nestjs/graphql major version 10

Hello, I have been using your amazing libraries for some years now.

Recently nestjs released a new version of their graphql implementation which breaks quite a lot of things.

As was recently brought up in PR #32 graphql-transport-ws is officially deprecated and fastify version 3 is not compatible with @nestjs/graphql version 8 which is the latest officially supported version of this package.

Anyway it is somehow currently possible to use this package with @nestjs/graphql version 9 to use graphql-ws as I have been doing in my projects.

As I need this package for my current projects, for the time being I forked this repo and updated the dependencies and integration myself. (https://github.com/GlCap/typegraphql-nestjs)

Just wanted to let you know, I am willing to publish a PR with my fork. However I have no need for the federation module, and honestly I have no idea how to implement an integration for it, as I never even used GraphQL Federation myself.

Thanks for your time.

Yoga federation driver support

Hi @MichalLytek, I'm writing you because I'm currently splitting my monolith graph into microservices but I encountered an issue.
My stack is composed by Nestjs (v10.0.0) + typegraphql-nestjs (v0.6.0) + Yoga GraphQL (v5.0.0).

To achieve the migration to microservices I'm going to use the Federation V2 with the YogaFederationDriver.
Here's my main module after the migration:

import * as path from 'path';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';
import { YogaFederationDriver } from '@graphql-yoga/nestjs-federation';
import { TypeGraphQLModule } from 'typegraphql-nestjs';
import { UserModule } from './user/user.module';
import { SubGraphRequest } from './dto/types/request.type';

@Module({
 imports: [
   ConfigModule.forRoot(),
   MongooseModule.forRoot(process.env.MONGODB_URL, {
     maxPoolSize: 10,
   }),

   TypeGraphQLModule.forRootAsync({
     driver: YogaFederationDriver,
     useFactory: () => ({
       federationVersion: 2,
       emitSchemaFile: path.join(__dirname, '..', 'schema.graphQL'),
       context: async ({ req }: { req: SubGraphRequest }) => {
         return {
           email: req.get('x-user-email')
         };
       }
     }),
   }),
   
   // my modules 
   UserModule,
 ],
})
export class AppModule {}

Unfortunately this generates the graphql schema error:

/user-subgraph/node_modules/@apollo/federation-internals/src/error.ts:36
  err: (message: string, options?: GraphQLErrorOptions) => new GraphQLError(
                                                           ^
GraphQLError: Type User must define one or more fields.

After a deep investigation I found the issue is caused by the following line and I noticed that for the federation part the supported driver is ApolloFederationDriver from @nestjs/apollo

const isFederatedModule = driver === ApolloFederationDriver;

I tried to change this line with this one
const isFederatedModule = driver === ApolloFederationDriver || driver === YogaFederatedDrivers;
and it seems to work.

Is this the expected behaviour? Is it possible to extend the support to Yoga Federated Drivers and the other available drivers?

And also maybe it could be useful to check the federation version instead of the drivers types, for example
const isFederatedModule = federationVersion === 1 | federationVersion === 2;

Possibility to emit schema file in offline context

Currently, the plugin only emits a schema file on runtime, but this is not ideal for designing a microservice architecture, when other services depend on that schema file for generating their own code.

Is there a possibility to emit the schema file without having to run the NestJS server?

Upgrade doc for TypegraphqlModule.forRootAsync

Hi, I tried the TypeGraphQLModule.forRootAsync from the documentation

The code doesn't work (since graphql v10+)

I had hints of how to resolve it thanks to nestjs/graphql#2004 (answer by kamilmysliwiec)

Here is the code that made it work, since I'm not used to working with forRootAsync, I think it will help people like me ^^

const prisma = new PrismaClient();
    export interface Context {
      prisma: PrismaClient
    }
@Module({
  imports: [ /*all other things*/
    TypeGraphQLModule.forRootAsync({
      driver: ApolloDriver, // <--- "driver" should be here, as shown in the docs
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        return {
          context: (): Context => ({ prisma }),
          emitSchemaFile: "./generated-schema.graphql",
          playground: true,
          validate: false,
          dateScalarMode: "timestamp",
          path: "/",
          pollIntervalInMs: 5000
        } as GqlModuleOptions;
      },
    }),
    ],
    controllers: [/* ... */],
    providers : [/* ... */],
    })

Scoped providers - Undefined REQUEST injection

When I want to declare a scoped provider, to get a value from request and inject it.

I need to inject the REQUEST to have the express request object inside a provider.

When I call other nestJS rest endpoint, it's working.
And when I use the nestJS graphQL module, it's working too.

But, with typeGraphQL one, when I call the graphQL endpoint, I have an undefined value, like the REQUEST is not injected.

Here the provider declaration.
The goal is to inject value as provider from the request object (generated by a middleware)

  {
    provide: Config,
    scope: Scope.REQUEST,
    useFactory: (request: any): Config => {
      console.log(request);

      return request.config;
    },
    inject: ['REQUEST'],
  }

When I debug, here the contextId is undefined:

let contextId = context[REQUEST_CONTEXT_ID];

Custom AuthChecker not running upon request in TypeGraphQL with NestJS

Describe the Bug

The AuthChecker function is not being called when a request is made to a GraphQL endpoint that has @Authorized decorators applied to its resolvers or fields. Despite properly configuring the authChecker option in the TypeGraphQLModule and providing a custom AuthChecker implementation, the authentication logic is not triggered.

To Reproduce

Here's a minimal reproducible example:

// app.module.ts
import { Module } from '@nestjs/common';
import { TypeGraphQLModule } from 'typegraphql-nestjs';
import { CustomAuthChecker } from './authorization/authChecker';
import { AuthorizationGuard } from './authorization/authorization.guard';
import { ConfigModule } from '@nestjs/config';

export interface GraphQLContext {
  req: any;
  res: any;
}

@Module({
  imports: [
    TypeGraphQLModule.forRoot({
      authChecker: CustomAuthChecker,
      authMode: 'error',
      context: ({ req, res }): GraphQLContext => ({
        req,
        res,
      }),
    }),
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
  providers: [AuthorizationGuard],
})
export class AppModule {}

// authorization.guard.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { expressjwt as jwt } from 'express-jwt';
import { promisify } from 'util';
import { expressJwtSecret, GetVerificationKey } from 'jwks-rsa';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class AuthorizationGuard {
  private AUTH0_DOMAIN;
  private AUTH0_AUDIENCE;

  constructor(private configService: ConfigService) {
    this.AUTH0_DOMAIN = this.configService.get('AUTH0_DOMAIN');
    this.AUTH0_AUDIENCE = this.configService.get('AUTH0_AUDIENCE');
  }

  async checkAuth(req: any, res: any): Promise<boolean> {
    try {
      await this.checkJwt(req, res);
      return true;
    } catch (e) {
      return false;
    }
  }

  private async checkJwt(req: any, res: any): Promise<void> {
    const checkJwt = promisify(
      jwt({
        secret: expressJwtSecret({
          cache: true,
          rateLimit: true,
          jwksRequestsPerMinute: 5,
          jwksUri: `https://${this.AUTH0_DOMAIN}/.well-known/jwks.json`,
        }) as GetVerificationKey,
        audience: this.AUTH0_AUDIENCE,
        issuer: this.AUTH0_DOMAIN,
        algorithms: ['RS256'],
      }),
    );

    await checkJwt(req, res);
  }
}

// authChecker.ts
import { AuthCheckerInterface, ResolverData } from 'type-graphql';
import { AuthorizationGuard } from './authorization.guard';
import { Logger } from '@nestjs/common';
import { GraphQLContext } from '../app.module';

export class CustomAuthChecker implements AuthCheckerInterface<GraphQLContext> {
  constructor(private readonly authorizationGuard: AuthorizationGuard) {}

  async check(
    resolverData: ResolverData<GraphQLContext>,
    roles: string[],
  ): Promise<boolean> {
    Logger.debug('Checking auth', 'CustomAuthChecker');
    const { req, res } = resolverData.context;
    try {
      await this.authorizationGuard.checkAuth(req, res);
      return true;
    } catch (error) {
      return false;
    }
  }
}

The CustomAuthChecker is provided to the TypeGraphQLModule via the authChecker option, but when making a request to a GraphQL endpoint decorated with @Authorized, the check method of CustomAuthChecker is not invoked, and consequently, the AuthorizationGuard.checkAuth method is not called.

Expected Behavior

When a request is made to a GraphQL endpoint decorated with @Authorized, the check method of the CustomAuthChecker should be invoked, and the AuthorizationGuard.checkAuth method should be called to perform the authentication logic. If the authentication succeeds, the request should proceed; otherwise, it should be rejected with an unauthorized error.

Logs

The Logger.debug('Checking auth', 'CustomAuthChecker'); statement inside the CustomAuthChecker.check method is not being logged, indicating that the check method is not being invoked.

Environment:

Additional Context

I have followed the documentation and examples provided in the TypeGraphQL and typegraphql-nestjs repositories, but the AuthChecker is still not being triggered. I have also ensured that the @Authorized decorators are properly applied to the resolvers or fields in my GraphQL schema.

0.3.0 breaks compilation with current Nest.js version

Using the 0.3.0 version of this package breaks compilation with the following error:

Nest can't resolve dependencies of the TypeGraphQLOptionsFactory (TYPEGRAPHQL_ROOT_MODULE_OPTIONS, ?). Please make sure that the argument OptionsPreparatorService at index [1] is available in the GraphQLModule context.

Potential solutions:
- If OptionsPreparatorService is a provider, is it part of the current GraphQLModule?
- If OptionsPreparatorService is exported from a separate @Module, is that module imported within GraphQLModule?
  @Module({
    imports: [ /* the Module containing OptionsPreparatorService */ ]
  })
 +1ms
Error: Nest can't resolve dependencies of the TypeGraphQLOptionsFactory (TYPEGRAPHQL_ROOT_MODULE_OPTIONS, ?). Please make sure that the argument OptionsPreparatorService at index [1] is available in the GraphQLModule context.

Potential solutions:
- If OptionsPreparatorService is a provider, is it part of the current GraphQLModule?
- If OptionsPreparatorService is exported from a separate @Module, is that module imported within GraphQLModule?
  @Module({
    imports: [ /* the Module containing OptionsPreparatorService */ ]
  })

    at Injector.lookupComponentInParentModules (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:188:19)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Injector.resolveComponentInstance (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:144:33)
    at async resolveParam (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:98:38)
    at async Promise.all (index 1)
    at async Injector.resolveConstructorParams (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:113:27)
    at async Injector.loadInstance (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:46:9)
    at async Injector.loadProvider (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/injector.js:68:9)
    at async Promise.all (index 13)
    at async InstanceLoader.createInstancesOfProviders (/Users/johannesklauss/Documents/Development/Syra/node_modules/@nestjs/core/injector/instance-loader.js:43:9)

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

These are my used nest packages:

    "@nestjs-modules/mailer": "1.5.1",
    "@nestjs/bull": "0.3.1",
    "@nestjs/common": "7.6.15",
    "@nestjs/config": "0.6.3",
    "@nestjs/core": "7.6.15",
    "@nestjs/graphql": "7.10.3",
    "@nestjs/jwt": "7.2.0",
    "@nestjs/microservices": "7.6.15",
    "@nestjs/passport": "7.1.5",
    "@nestjs/platform-fastify": "7.6.15",

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.