Skip to content

Commit

Permalink
refactor: queryHook
Browse files Browse the repository at this point in the history
  • Loading branch information
neil585456525 committed Oct 12, 2023
1 parent 39530e5 commit 8789c7a
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
parseMapper,
} from '@graphql-codegen/visitor-plugin-common';
import { CustomFetch } from './config.js';
import { FetcherRenderer } from './fetcher.js';
import { FetcherRenderer, type GenerateQueryHookConfig } from './fetcher.js';
import { ReactQueryVisitor } from './visitor.js';

export class CustomMapperFetcher extends FetcherRenderer {
Expand Down Expand Up @@ -90,14 +90,16 @@ export class CustomMapperFetcher extends FetcherRenderer {
)};`;
}

generateQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
operationName: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string {
generateQueryHook(config: GenerateQueryHookConfig): string {
const {
node,
documentVariableName,
operationName,
operationResultType,
operationVariablesTypes,
hasRequiredVariables,
} = config;

const variables = `variables${hasRequiredVariables ? '' : '?'}: ${operationVariablesTypes}`;

const hookConfig = this.visitor.queryMethodMap;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import autoBind from 'auto-bind';
import { OperationDefinitionNode } from 'graphql';
import { HardcodedFetch } from './config.js';
import { FetcherRenderer } from './fetcher.js';
import { FetcherRenderer, type GenerateQueryHookConfig } from './fetcher.js';
import { ReactQueryVisitor } from './visitor.js';

export class HardcodedFetchFetcher extends FetcherRenderer {
Expand Down Expand Up @@ -93,14 +93,16 @@ ${this.getFetchParams()}
);`;
}

generateQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
operationName: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string {
generateQueryHook(config: GenerateQueryHookConfig): string {
const {
node,
documentVariableName,
operationName,
operationResultType,
operationVariablesTypes,
hasRequiredVariables,
} = config;

const variables = this.generateQueryVariablesSignature(
hasRequiredVariables,
operationVariablesTypes,
Expand Down
39 changes: 9 additions & 30 deletions packages/plugins/typescript/react-query/src/fetcher-fetch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import autoBind from 'auto-bind';
import { OperationDefinitionNode } from 'graphql';
import { FetcherRenderer } from './fetcher.js';
import { FetcherRenderer, type GenerateQueryHookConfig } from './fetcher.js';
import { ReactQueryVisitor } from './visitor.js';

export class FetchFetcher extends FetcherRenderer {
Expand Down Expand Up @@ -69,38 +69,17 @@ function fetcher<TData, TVariables>(endpoint: string, requestInit: RequestInit,
);`;
}

generateQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
operationName: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string {
const variables = this.generateQueryVariablesSignature(
hasRequiredVariables,
operationVariablesTypes,
);
const hookConfig = this.visitor.queryMethodMap;
this.visitor.reactQueryHookIdentifiersInUse.add(hookConfig.query.hook);
this.visitor.reactQueryOptionsIdentifiersInUse.add(hookConfig.query.options);
generateQueryHook(config: GenerateQueryHookConfig): string {
const { generateBaseQueryHook, variables, options } = this.generateQueryHelper(config);

const options = `options?: ${hookConfig.query.options}<${operationResultType}, TError, TData>`;
const { documentVariableName, operationResultType, operationVariablesTypes } = config;

return `export const use${operationName} = <
TData = ${operationResultType},
TError = ${this.visitor.config.errorType}
>(
dataSource: { endpoint: string, fetchParams?: RequestInit },
return generateBaseQueryHook({
implArguments: `dataSource: { endpoint: string, fetchParams?: RequestInit },
${variables},
${options}
) =>
${hookConfig.query.hook}<${operationResultType}, TError, TData>(
${this.generateQueryFormattedParameters(
this.generateQueryKey(node, hasRequiredVariables),
`fetcher<${operationResultType}, ${operationVariablesTypes}>(dataSource.endpoint, dataSource.fetchParams || {}, ${documentVariableName}, variables)`,
)}
);`;
${options}`,
implFetcher: `fetcher<${operationResultType}, ${operationVariablesTypes}>(dataSource.endpoint, dataSource.fetchParams || {}, ${documentVariableName}, variables)`,
});
}

generateMutationHook(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import autoBind from 'auto-bind';
import { OperationDefinitionNode } from 'graphql';
import { GraphQlRequest } from './config.js';
import { FetcherRenderer } from './fetcher.js';
import { FetcherRenderer, type GenerateQueryHookConfig } from './fetcher.js';
import { ReactQueryVisitor } from './visitor.js';

export class GraphQLRequestClientFetcher extends FetcherRenderer {
Expand Down Expand Up @@ -92,14 +92,16 @@ function fetcher<TData, TVariables extends { [key: string]: any }>(client: Graph
);`;
}

generateQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
operationName: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string {
generateQueryHook(config: GenerateQueryHookConfig): string {
const {
node,
documentVariableName,
operationName,
operationResultType,
operationVariablesTypes,
hasRequiredVariables,
} = config;

const variables = this.generateQueryVariablesSignature(
hasRequiredVariables,
operationVariablesTypes,
Expand Down
72 changes: 63 additions & 9 deletions packages/plugins/typescript/react-query/src/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,72 @@ import autoBind from 'auto-bind';
import { OperationDefinitionNode } from 'graphql';
import { ReactQueryVisitor } from './visitor.js';

export interface GenerateQueryHookConfig {
node: OperationDefinitionNode;
documentVariableName: string;
operationName: string;
operationResultType: string;
operationVariablesTypes: string;
hasRequiredVariables: boolean;
}

export class BaseFetcherRenderer {
constructor(protected visitor: ReactQueryVisitor) {
autoBind(this);
}

generateQueryHelper() {}
generateQueryHelper(config: GenerateQueryHookConfig) {
const {
node,
operationName,
operationResultType,
operationVariablesTypes,
hasRequiredVariables,
} = config;

const variables = this.generateQueryVariablesSignature(
hasRequiredVariables,
operationVariablesTypes,
);
const hookConfig = this.visitor.queryMethodMap;
this.visitor.reactQueryHookIdentifiersInUse.add(hookConfig.query.hook);
this.visitor.reactQueryOptionsIdentifiersInUse.add(hookConfig.query.options);

const options = `options?: ${hookConfig.query.options}<${operationResultType}, TError, TData>`;

const generateBaseQueryHook = (config: {
implArguments?: string;
implHookOuter?: string;
implFetcher: string;
}) => {
const { implArguments = '', implHookOuter = '', implFetcher = '' } = config;

const argumentsResult =
implArguments ??
`${variables},
${options}`;

return `export const use${operationName} = <
TData = ${operationResultType},
TError = ${this.visitor.config.errorType}
>(
${argumentsResult}
) => {
${implHookOuter}
return ${hookConfig.query.hook}<${operationResultType}, TError, TData>(
${this.generateQueryFormattedParameters(
this.generateQueryKey(node, hasRequiredVariables),
implFetcher,
)}
)};`;
};

return {
generateBaseQueryHook,
variables,
options,
};
}

generateQueryVariablesSignature(
hasRequiredVariables: boolean,
Expand Down Expand Up @@ -143,16 +203,10 @@ export class BaseFetcherRenderer {
}`;
}
}

export abstract class FetcherRenderer extends BaseFetcherRenderer {
abstract generateFetcherImplementation(): string;
abstract generateQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
operationName: string,
operationResultType: string,
operationVariablesTypes: string,
hasRequiredVariables: boolean,
): string;
abstract generateQueryHook(config: GenerateQueryHookConfig): string;
abstract generateInfiniteQueryHook(
node: OperationDefinitionNode,
documentVariableName: string,
Expand Down
4 changes: 2 additions & 2 deletions packages/plugins/typescript/react-query/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,14 @@ export class ReactQueryVisitor extends ClientSideBaseVisitor<
operationVariablesTypes = this._externalImportPrefix + operationVariablesTypes;

if (operationType === 'Query') {
let query = this.fetcher.generateQueryHook(
let query = this.fetcher.generateQueryHook({
node,
documentVariableName,
operationName,
operationResultType,
operationVariablesTypes,
hasRequiredVariables,
);
});
if (this.config.exposeDocument) {
query += `\nuse${operationName}.document = ${documentVariableName};\n`;
}
Expand Down
Loading

0 comments on commit 8789c7a

Please sign in to comment.