1
- import { addResolveFunctionsToSchema } from 'graphql-tools-fork' ;
2
- import { GraphQLSchema , GraphQLResolveInfo } from 'graphql' ;
1
+ import { GraphQLResolveInfo } from 'graphql' ;
3
2
import { TransformFn , YamlConfig } from '@graphql-mesh/types' ;
4
3
import {
5
4
composeResolvers ,
@@ -26,77 +25,77 @@ interpolator.registerModifier('hash', (value: any) =>
26
25
) ;
27
26
28
27
export const cacheTransform : TransformFn < YamlConfig . CacheTransformConfig [ ] > = async ( {
29
- schema,
30
28
config,
31
29
cache,
32
30
hooks
33
- } ) : Promise < GraphQLSchema > => {
34
- const sourceResolvers = extractResolversFromSchema ( schema ) ;
35
- const compositions : ResolversComposerMapping = { } ;
36
-
37
- for ( const cacheItem of config ) {
38
- const effectingOperations = cacheItem . invalidate ?. effectingOperations || [ ] ;
39
-
40
- if ( effectingOperations . length > 0 ) {
41
- hooks . on ( 'resolverDone' , async ( resolverInfo , result ) => {
42
- const effectingRule = effectingOperations . find (
43
- o =>
44
- o . operation ===
45
- `${ resolverInfo . info . parentType . name } .${ resolverInfo . info . fieldName } `
46
- ) ;
47
-
48
- if ( effectingRule ) {
31
+ } ) : Promise < void > => {
32
+ // We need to use `schemaReady` hook and not the schema directly because we need to make sure to run cache after all
33
+ // other transformations are done, and to make sure that custom resolve are already loaded and merged into the schema
34
+ hooks . on ( 'schemaReady' , ( { schema, applyResolvers } ) => {
35
+ const sourceResolvers = extractResolversFromSchema ( schema ) ;
36
+ const compositions : ResolversComposerMapping = { } ;
37
+
38
+ for ( const cacheItem of config ) {
39
+ const effectingOperations =
40
+ cacheItem . invalidate ?. effectingOperations || [ ] ;
41
+
42
+ if ( effectingOperations . length > 0 ) {
43
+ hooks . on ( 'resolverDone' , async ( resolverInfo , result ) => {
44
+ const effectingRule = effectingOperations . find (
45
+ o =>
46
+ o . operation ===
47
+ `${ resolverInfo . info . parentType . name } .${ resolverInfo . info . fieldName } `
48
+ ) ;
49
+
50
+ if ( effectingRule ) {
51
+ const cacheKey = computeCacheKey ( {
52
+ keyStr : effectingRule . matchKey ,
53
+ args : resolverInfo . args ,
54
+ info : resolverInfo . info
55
+ } ) ;
56
+
57
+ await cache . delete ( cacheKey ) ;
58
+ }
59
+ } ) ;
60
+ }
61
+
62
+ compositions [ cacheItem . field ] = < ResolversComposition > (
63
+ ( originalResolver => async (
64
+ root : any ,
65
+ args : any ,
66
+ context : any ,
67
+ info : GraphQLResolveInfo
68
+ ) => {
49
69
const cacheKey = computeCacheKey ( {
50
- keyStr : effectingRule . matchKey ,
51
- args : resolverInfo . args ,
52
- info : resolverInfo . info
70
+ keyStr : cacheItem . cacheKey ,
71
+ args,
72
+ info
53
73
} ) ;
54
74
55
- await cache . delete ( cacheKey ) ;
56
- }
57
- } ) ;
58
- }
59
-
60
- compositions [ cacheItem . field ] = < ResolversComposition > (
61
- ( originalResolver => async (
62
- root : any ,
63
- args : any ,
64
- context : any ,
65
- info : GraphQLResolveInfo
66
- ) => {
67
- const cacheKey = computeCacheKey ( {
68
- keyStr : cacheItem . cacheKey ,
69
- args,
70
- info
71
- } ) ;
72
-
73
- const cachedValue = await cache . get ( cacheKey ) ;
75
+ const cachedValue = await cache . get ( cacheKey ) ;
74
76
75
- if ( cachedValue ) {
76
- return cachedValue ;
77
- }
77
+ if ( cachedValue ) {
78
+ return cachedValue ;
79
+ }
78
80
79
- const resolverResult = await originalResolver (
80
- root ,
81
- args ,
82
- context ,
83
- info
84
- ) ;
81
+ const resolverResult = await originalResolver (
82
+ root ,
83
+ args ,
84
+ context ,
85
+ info
86
+ ) ;
85
87
86
- await cache . set ( cacheKey , resolverResult , {
87
- ttl : cacheItem . invalidate ?. ttl || undefined
88
- } ) ;
89
-
90
- return resolverResult ;
91
- } )
92
- ) ;
93
- }
88
+ await cache . set ( cacheKey , resolverResult , {
89
+ ttl : cacheItem . invalidate ?. ttl || undefined
90
+ } ) ;
94
91
95
- const wrappedResolvers = composeResolvers ( sourceResolvers , compositions ) ;
92
+ return resolverResult ;
93
+ } )
94
+ ) ;
95
+ }
96
96
97
- return addResolveFunctionsToSchema ( {
98
- schema,
99
- resolvers : wrappedResolvers
97
+ const wrappedResolvers = composeResolvers ( sourceResolvers , compositions ) ;
98
+ applyResolvers ( wrappedResolvers ) ;
100
99
} ) ;
101
100
} ;
102
101
@@ -106,8 +105,8 @@ export function computeCacheKey(options: {
106
105
info : GraphQLResolveInfo ;
107
106
} ) : string {
108
107
const argsHash = options . args
109
- ? objectHash ( options . args , { ignoreUnknown : true } )
110
- : '' ;
108
+ ? objectHash ( options . args , { ignoreUnknown : true } )
109
+ : '' ;
111
110
112
111
if ( ! options . keyStr ) {
113
112
return `${ options . info . parentType . name } -${ options . info . fieldName } -${ argsHash } ` ;
0 commit comments