-
Notifications
You must be signed in to change notification settings - Fork 569
/
index.ts
123 lines (108 loc) · 3.54 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { GraphQLSchema } from 'graphql';
import { ApolloGateway, GatewayConfig } from '@apollo/gateway';
import { printSubgraphSchema } from '@apollo/subgraph';
import { useApolloFederation } from '@envelop/apollo-federation';
import {
AbstractYogaDriver,
YogaDriver,
YogaDriverConfig,
YogaDriverPlatform,
} from '@graphql-yoga/nestjs';
import { useApolloInlineTrace } from '@graphql-yoga/plugin-apollo-inline-trace';
import { Injectable, Type } from '@nestjs/common';
import {
GqlSubscriptionService,
GraphQLFederationFactory,
SubscriptionConfig,
} from '@nestjs/graphql';
export type YogaFederationDriverConfig<Platform extends YogaDriverPlatform = 'express'> =
YogaDriverConfig<Platform>;
@Injectable()
export class YogaFederationDriver<
Platform extends YogaDriverPlatform = 'express',
> extends AbstractYogaDriver<Platform> {
private subscriptionService?: GqlSubscriptionService;
constructor(private readonly graphqlFederationFactory: GraphQLFederationFactory) {
super();
}
async generateSchema(options: YogaFederationDriverConfig<Platform>): Promise<GraphQLSchema> {
return await this.graphqlFederationFactory.generateSchema(options);
}
public async start(options: YogaFederationDriverConfig<Platform>) {
if (options.definitions?.path) {
if (!options.schema) {
throw new Error('Schema is required when providing definitions path');
}
await this.graphQlFactory.generateDefinitions(printSubgraphSchema(options.schema), options);
}
await super.start({
...options,
plugins: [...(options?.plugins || []), useApolloInlineTrace()],
});
if (options.subscriptions && options.schema) {
const config: SubscriptionConfig =
options.subscriptions === true
? {
'graphql-ws': true,
}
: options.subscriptions;
this.subscriptionService = new GqlSubscriptionService(
{
schema: options.schema,
path: options.path,
context: options.context,
...config,
},
this.httpAdapterHost.httpAdapter?.getHttpServer(),
);
}
}
public async stop(): Promise<void> {
await this.subscriptionService?.stop();
}
}
export interface YogaGatewayDriverConfig<Platform extends YogaDriverPlatform = 'express'> {
driver?: Type<YogaDriver<Platform>>;
gateway?: GatewayConfig;
server?: Omit<
YogaDriverConfig<Platform>,
| 'endpoint'
| 'schema'
| 'typeDefs'
| 'definitions'
| 'resolvers'
| 'resolverValidationOptions'
| 'directiveResolvers'
| 'autoSchemaFile'
| 'transformSchema'
| 'subscriptions'
| 'buildSchemaOptions'
| 'fieldResolverEnhancers'
| 'driver'
>;
}
@Injectable()
export class YogaGatewayDriver<
Platform extends YogaDriverPlatform = 'express',
> extends AbstractYogaDriver<Platform> {
public async generateSchema(_options: YogaGatewayDriverConfig<Platform>): Promise<GraphQLSchema> {
return new GraphQLSchema({});
}
public async start(options: YogaGatewayDriverConfig<Platform>) {
const { server: serverOpts = {}, gateway: gatewayOpts = {} } = options;
const gateway: ApolloGateway = new ApolloGateway(gatewayOpts);
await gateway.load();
await super.start({
...serverOpts,
plugins: [...(serverOpts.plugins || []), useApolloFederation({ gateway })],
});
}
public async mergeDefaultOptions(
options: Record<string, unknown>,
): Promise<Record<string, unknown>> {
return {
...options,
server: await super.mergeDefaultOptions(options?.server ?? {}),
};
}
}