Skip to content

Commit ebda807

Browse files
feature(modules): add .forRootAsync() support (#8)
Co-authored-by: Michał Lytek <michal.wojciech.lytek@gmail.com>
1 parent fb67e94 commit ebda807

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

README.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ npm i type-graphql
2525

2626
## How to use?
2727

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

30-
It exposes two static methods. The first one is `TypeGraphQLModule.forRoot()` which you should call on your root module, just like with `GraphQLModule`.
30+
### `.forRoot()`
31+
32+
The first one is `TypeGraphQLModule.forRoot()` which you should call on your root module, just like with the official `GraphQLModule`.
3133

3234
The only difference is that as its argument you can provide [typical TypeGraphQL `buildSchema` options](https://typegraphql.com/docs/bootstrap.html) like `emitSchemaFile` or `authChecker` apart from the [standard `GqlModuleOptions` from `@nestjs/graphql`](https://docs.nestjs.com/graphql/quick-start#installation) like `installSubscriptionHandlers` or `context`:
3335

@@ -71,6 +73,8 @@ And that's it! 😁
7173

7274
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()`.
7375

76+
### `.forFeature()`
77+
7478
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:
7579

7680
```ts
@@ -94,6 +98,34 @@ export default class RecipeModule {}
9498

9599
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.
96100

101+
### `.forRootAsync()`
102+
103+
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.
104+
105+
Example of using the config service to generate `TypeGraphQLModule` options:
106+
107+
```ts
108+
@Module({
109+
imports: [
110+
ConfigModule,
111+
RecipeModule,
112+
TypeGraphQLModule.forRootAsync({
113+
inject: [ConfigService],
114+
useFactory: async (config: ConfigService) => ({
115+
cors: true,
116+
debug: config.isDevelopmentMode,
117+
playground: !config.isDevelopmentMode,
118+
validate: false,
119+
dateScalarMode: "timestamp",
120+
emitSchemaFile:
121+
config.isDevelopmentMode && path.resolve(__dirname, "schema.gql"),
122+
}),
123+
}),
124+
],
125+
})
126+
export default class AppModule {}
127+
```
128+
97129
## Caveats
98130

99131
While this integration provides a way to use TypeGraphQL with NestJS modules and dependency injector, for now it doesn't support [other NestJS features](https://docs.nestjs.com/graphql/tooling) like guards, interceptors, filters and pipes.

src/typegraphql.module.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import TypeGraphQLOptionsFactory from "./typegraphql-options.factory";
99
import {
1010
TypeGraphQLFeatureModuleOptions,
1111
TypeGraphQLRootModuleOptions,
12+
TypeGraphQLRootModuleAsyncOptions,
1213
} from "./types";
1314

1415
@Module({})
@@ -42,4 +43,23 @@ export class TypeGraphQLModule {
4243
],
4344
};
4445
}
46+
47+
static forRootAsync(
48+
asyncOptions: TypeGraphQLRootModuleAsyncOptions,
49+
): DynamicModule {
50+
const dynamicGraphQLModule = GraphQLModule.forRootAsync({
51+
useClass: TypeGraphQLOptionsFactory,
52+
});
53+
return {
54+
...dynamicGraphQLModule,
55+
providers: [
56+
...dynamicGraphQLModule.providers!,
57+
{
58+
inject: asyncOptions.inject,
59+
provide: TYPEGRAPHQL_ROOT_MODULE_OPTIONS,
60+
useFactory: asyncOptions.useFactory,
61+
},
62+
],
63+
};
64+
}
4565
}

src/types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { GqlModuleOptions } from "@nestjs/graphql";
21
import { BuildSchemaOptions } from "type-graphql";
2+
import { GqlModuleOptions } from "@nestjs/graphql";
3+
import { FactoryProvider, ModuleMetadata } from "@nestjs/common/interfaces";
34

45
export type TypeGraphQLFeatureModuleOptions = Pick<
56
BuildSchemaOptions,
@@ -11,3 +12,12 @@ export type TypeGraphQLRootModuleOptions = Omit<
1112
"schema" | "autoSchemaFile" | "buildSchemaOptions"
1213
> &
1314
Omit<BuildSchemaOptions, "resolvers" | "orphanedTypes" | "container">;
15+
16+
export interface TypeGraphQLRootModuleAsyncOptions
17+
extends Pick<ModuleMetadata, "imports">,
18+
Pick<
19+
FactoryProvider<
20+
Promise<TypeGraphQLRootModuleOptions> | TypeGraphQLRootModuleOptions
21+
>,
22+
"inject" | "useFactory"
23+
> {}

0 commit comments

Comments
 (0)