@@ -7,16 +7,21 @@ import { Injectable } from '@nestjs/common';
7
7
import { GqlOptionsFactory } from '@nestjs/graphql' ;
8
8
import { CacheService } from '@seedcompany/cache' ;
9
9
import { mapKeys } from '@seedcompany/common' ;
10
- import { GraphQLScalarType , OperationDefinitionNode } from 'graphql' ;
11
- import { Plugin } from 'graphql-yoga' ;
10
+ import {
11
+ DocumentNode ,
12
+ GraphQLScalarType ,
13
+ OperationDefinitionNode ,
14
+ } from 'graphql' ;
15
+ import { Plugin as PluginNoContext } from 'graphql-yoga' ;
12
16
import { BehaviorSubject } from 'rxjs' ;
13
- import { GqlContextType , ServerException , Session } from '~/common' ;
17
+ import { GqlContextType , Session } from '~/common' ;
14
18
import { getRegisteredScalars } from '~/common/scalars' ;
15
19
import { ConfigService } from '../config/config.service' ;
16
20
import { VersionService } from '../config/version.service' ;
17
21
import { isGqlContext } from './gql-context.host' ;
18
22
import { GraphqlTracingPlugin } from './graphql-tracing.plugin' ;
19
23
24
+ type Plugin = PluginNoContext < GqlContextType > ;
20
25
type ServerContext = YogaDriverServerContext < 'fastify' > ;
21
26
22
27
@Injectable ( )
@@ -54,14 +59,14 @@ export class GraphqlOptions implements GqlOptionsFactory {
54
59
maskedErrors : false , // Errors are formatted in plugin
55
60
sortSchema : true ,
56
61
buildSchemaOptions : {
57
- // fieldMiddleware: [this.tracing.fieldMiddleware()],
62
+ fieldMiddleware : [ this . tracing . fieldMiddleware ( ) ] ,
58
63
} ,
59
64
resolvers : {
60
65
...scalars ,
61
66
} ,
62
67
plugins : [
63
68
this . useAutomaticPersistedQueries ( ) ,
64
- // more ,
69
+ this . useAddOperationToContext ( ) ,
65
70
] ,
66
71
fetchAPI : {
67
72
// @whatwg -node/node-fetch polyfill doesn't keep square brackets for ipv6 hostname
@@ -75,17 +80,16 @@ export class GraphqlOptions implements GqlOptionsFactory {
75
80
context = ( {
76
81
req : request ,
77
82
reply : response ,
78
- } : ServerContext ) : GqlContextType => {
83
+ } : ServerContext ) : Partial < GqlContextType > => {
79
84
return {
80
85
[ isGqlContext . KEY ] : true ,
81
86
request,
82
87
response,
83
- operation : createFakeStubOperation ( ) ,
84
88
session$ : new BehaviorSubject < Session | undefined > ( undefined ) ,
85
89
} ;
86
90
} ;
87
91
88
- private useAutomaticPersistedQueries ( ) : Plugin | false {
92
+ private useAutomaticPersistedQueries ( ) : PluginNoContext | false {
89
93
const { enabled, ttl } = this . config . graphQL . persistedQueries ;
90
94
if ( ! enabled ) {
91
95
return false ;
@@ -94,13 +98,16 @@ export class GraphqlOptions implements GqlOptionsFactory {
94
98
const store = this . cache . namespace ( 'apq:' , { ttl, refreshTtlOnGet : true } ) ;
95
99
return useAPQ ( { store } ) ;
96
100
}
97
- }
98
101
99
- export const createFakeStubOperation = ( ) => {
100
- const operation = { } as unknown as OperationDefinitionNode ;
101
- return new Proxy ( operation , {
102
- get ( ) {
103
- throw new ServerException ( 'GQL operation has not been determined yet' ) ;
104
- } ,
105
- } ) ;
106
- } ;
102
+ private useAddOperationToContext ( ) : Plugin {
103
+ return {
104
+ onValidate : ( { params, extendContext } ) => {
105
+ const document : DocumentNode = params . documentAST ;
106
+ const operation = document . definitions . find (
107
+ ( d ) : d is OperationDefinitionNode => d . kind === 'OperationDefinition' ,
108
+ ) ! ;
109
+ extendContext ( { operation } ) ;
110
+ } ,
111
+ } ;
112
+ }
113
+ }
0 commit comments