UNPKG

5.87 kBJavaScriptView Raw
1import { buildMapperImport, parseMapper } from '@graphql-codegen/visitor-plugin-common';
2import { generateInfiniteQueryKey, generateMutationKey, generateQueryKey } from './variables-generator.js';
3export class CustomMapperFetcher {
4 constructor(visitor, customFetcher) {
5 this.visitor = visitor;
6 if (typeof customFetcher === 'string') {
7 customFetcher = { func: customFetcher };
8 }
9 this._mapper = parseMapper(customFetcher.func);
10 this._isReactHook = customFetcher.isReactHook;
11 }
12 getFetcherFnName(operationResultType, operationVariablesTypes) {
13 return `${this._mapper.type}<${operationResultType}, ${operationVariablesTypes}>`;
14 }
15 generateFetcherImplementaion() {
16 if (this._mapper.isExternal) {
17 return buildMapperImport(this._mapper.source, [
18 {
19 identifier: this._mapper.type,
20 asDefault: this._mapper.default,
21 },
22 ], this.visitor.config.useTypeImports);
23 }
24 return null;
25 }
26 generateInfiniteQueryHook(node, documentVariableName, operationName, operationResultType, operationVariablesTypes, hasRequiredVariables) {
27 const pageParamKey = `pageParamKey: keyof ${operationVariablesTypes}`;
28 const variables = `variables${hasRequiredVariables ? '' : '?'}: ${operationVariablesTypes}`;
29 const hookConfig = this.visitor.queryMethodMap;
30 this.visitor.reactQueryHookIdentifiersInUse.add(hookConfig.infiniteQuery.hook);
31 this.visitor.reactQueryOptionsIdentifiersInUse.add(hookConfig.infiniteQuery.options);
32 const options = `options?: ${hookConfig.infiniteQuery.options}<${operationResultType}, TError, TData>`;
33 const typedFetcher = this.getFetcherFnName(operationResultType, operationVariablesTypes);
34 const implHookOuter = this._isReactHook ? `const query = ${typedFetcher}(${documentVariableName})` : '';
35 const impl = this._isReactHook
36 ? `(metaData) => query({...variables, ...(metaData.pageParam ? {[pageParamKey]: metaData.pageParam} : {})})`
37 : `(metaData) => ${typedFetcher}(${documentVariableName}, {...variables, ...(metaData.pageParam ? {[pageParamKey]: metaData.pageParam} : {})})()`;
38 return `export const useInfinite${operationName} = <
39 TData = ${operationResultType},
40 TError = ${this.visitor.config.errorType}
41 >(
42 ${pageParamKey},
43 ${variables},
44 ${options}
45 ) =>{
46 ${implHookOuter}
47 return ${hookConfig.infiniteQuery.hook}<${operationResultType}, TError, TData>(
48 ${generateInfiniteQueryKey(node, hasRequiredVariables)},
49 ${impl},
50 options
51 )};`;
52 }
53 generateQueryHook(node, documentVariableName, operationName, operationResultType, operationVariablesTypes, hasRequiredVariables) {
54 const variables = `variables${hasRequiredVariables ? '' : '?'}: ${operationVariablesTypes}`;
55 const hookConfig = this.visitor.queryMethodMap;
56 this.visitor.reactQueryHookIdentifiersInUse.add(hookConfig.query.hook);
57 this.visitor.reactQueryOptionsIdentifiersInUse.add(hookConfig.query.options);
58 const options = `options?: ${hookConfig.query.options}<${operationResultType}, TError, TData>`;
59 const typedFetcher = this.getFetcherFnName(operationResultType, operationVariablesTypes);
60 const impl = this._isReactHook
61 ? `${typedFetcher}(${documentVariableName}).bind(null, variables)`
62 : `${typedFetcher}(${documentVariableName}, variables)`;
63 return `export const use${operationName} = <
64 TData = ${operationResultType},
65 TError = ${this.visitor.config.errorType}
66 >(
67 ${variables},
68 ${options}
69 ) =>
70 ${hookConfig.query.hook}<${operationResultType}, TError, TData>(
71 ${generateQueryKey(node, hasRequiredVariables)},
72 ${impl},
73 options
74 );`;
75 }
76 generateMutationHook(node, documentVariableName, operationName, operationResultType, operationVariablesTypes, hasRequiredVariables) {
77 const variables = `variables?: ${operationVariablesTypes}`;
78 const hookConfig = this.visitor.queryMethodMap;
79 this.visitor.reactQueryHookIdentifiersInUse.add(hookConfig.mutation.hook);
80 this.visitor.reactQueryOptionsIdentifiersInUse.add(hookConfig.mutation.options);
81 const options = `options?: ${hookConfig.mutation.options}<${operationResultType}, TError, ${operationVariablesTypes}, TContext>`;
82 const typedFetcher = this.getFetcherFnName(operationResultType, operationVariablesTypes);
83 const impl = this._isReactHook
84 ? `${typedFetcher}(${documentVariableName})`
85 : `(${variables}) => ${typedFetcher}(${documentVariableName}, variables)()`;
86 return `export const use${operationName} = <
87 TError = ${this.visitor.config.errorType},
88 TContext = unknown
89 >(${options}) =>
90 ${hookConfig.mutation.hook}<${operationResultType}, TError, ${operationVariablesTypes}, TContext>(
91 ${generateMutationKey(node)},
92 ${impl},
93 options
94 );`;
95 }
96 generateFetcherFetch(node, documentVariableName, operationName, operationResultType, operationVariablesTypes, hasRequiredVariables) {
97 // We can't generate a fetcher field since we can't call react hooks outside of a React Fucntion Component
98 // Related: https://reactjs.org/docs/hooks-rules.html
99 if (this._isReactHook)
100 return '';
101 const variables = `variables${hasRequiredVariables ? '' : '?'}: ${operationVariablesTypes}`;
102 const typedFetcher = this.getFetcherFnName(operationResultType, operationVariablesTypes);
103 const impl = `${typedFetcher}(${documentVariableName}, variables, options)`;
104 return `\nuse${operationName}.fetcher = (${variables}, options?: RequestInit['headers']) => ${impl};`;
105 }
106}