From 6d090c8953713b980b66aa796db62f581e13b4c9 Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Thu, 21 Nov 2024 13:33:27 +0100 Subject: [PATCH 1/8] breaking change: Change query operation to object; Update generate query components to use query function; Add suspense query to the generation; Update context --- .../src/core/createOperationQueryFnNodes.ts | 326 +++++++----------- .../generateReactQueryComponents.test.ts | 286 +++++++++++---- .../generateReactQueryComponents.ts | 174 +++++----- .../generateReactQueryFunctions.test.ts | 63 +--- plugins/typescript/src/templates/context.ts | 9 +- 5 files changed, 449 insertions(+), 409 deletions(-) diff --git a/plugins/typescript/src/core/createOperationQueryFnNodes.ts b/plugins/typescript/src/core/createOperationQueryFnNodes.ts index f77b960f..fa5ac2fb 100644 --- a/plugins/typescript/src/core/createOperationQueryFnNodes.ts +++ b/plugins/typescript/src/core/createOperationQueryFnNodes.ts @@ -66,219 +66,145 @@ export const createOperationQueryFnNodes = ({ undefined ), ], - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("queryKey"), - undefined, - f.createTypeReferenceNode( - f.createQualifiedName( - f.createIdentifier("reactQuery"), - f.createIdentifier("QueryKey") - ), - undefined - ) - ), - f.createPropertySignature( - undefined, - f.createIdentifier("queryFn"), - undefined, - f.createFunctionTypeNode( - undefined, - verb === "get" - ? [ - f.createParameterDeclaration( - undefined, - undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), - undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken(ts.SyntaxKind.QuestionToken), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), - undefined - ), - ] - : [ - f.createParameterDeclaration( - undefined, - undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("variables"), - undefined - ), - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), - undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("variables"), - undefined, - variablesType - ), - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken(ts.SyntaxKind.QuestionToken), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), - undefined - ), - ], - f.createTypeReferenceNode(f.createIdentifier("Promise"), [dataType]) - ) - ), - ]), - + undefined, + f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - f.createObjectLiteralExpression( + f.createCallExpression( + f.createPropertyAccessExpression( + f.createIdentifier("reactQuery"), + f.createIdentifier("queryOptions") + ), + undefined, [ - f.createPropertyAssignment( - f.createIdentifier("queryKey"), - f.createCallExpression( - f.createIdentifier("queryKeyFn"), - undefined, - [ - f.createObjectLiteralExpression( - [ - f.createPropertyAssignment( - f.createIdentifier("path"), - f.createStringLiteral(camelizedPathParams(url)) - ), - f.createPropertyAssignment( - f.createIdentifier("operationId"), - f.createStringLiteral(operationId) - ), - f.createShorthandPropertyAssignment( - f.createIdentifier("variables"), - undefined - ), - ], - true - ), - ] - ) - ), - f.createPropertyAssignment( - f.createIdentifier("queryFn"), - f.createArrowFunction( - [f.createModifier(ts.SyntaxKind.AsyncKeyword)], - undefined, - verb === "get" - ? [ - f.createParameterDeclaration( - undefined, - undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), - undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken(ts.SyntaxKind.QuestionToken), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), - undefined - ), - ] - : [ - f.createParameterDeclaration( - undefined, - undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("variables"), - undefined - ), - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), - undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("variables"), - undefined, - variablesType - ), - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken(ts.SyntaxKind.QuestionToken), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), - undefined - ), - ], - undefined, - f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + f.createObjectLiteralExpression( + [ + f.createPropertyAssignment( + f.createIdentifier("queryKey"), f.createCallExpression( - f.createIdentifier(operationFetcherFnName), + f.createIdentifier("queryKeyFn"), undefined, [ f.createObjectLiteralExpression( [ - f.createSpreadAssignment( - f.createIdentifier("variables") + f.createPropertyAssignment( + f.createIdentifier("path"), + f.createStringLiteral( + camelizedPathParams(url) + ) + ), + f.createPropertyAssignment( + f.createIdentifier("operationId"), + f.createStringLiteral(operationId) + ), + f.createShorthandPropertyAssignment( + f.createIdentifier("variables"), + undefined ), ], - false + true ), - f.createIdentifier("signal"), ] ) - ) + ), + f.createPropertyAssignment( + f.createIdentifier("queryFn"), + f.createArrowFunction( + undefined, + undefined, + verb === "get" + ? [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("signal"), + undefined + ), + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("signal"), + f.createToken( + ts.SyntaxKind.QuestionToken + ), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) + ), + ]), + undefined + ), + ] + : [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("variables"), + undefined + ), + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("signal"), + undefined + ), + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("variables"), + undefined, + variablesType + ), + f.createPropertySignature( + undefined, + f.createIdentifier("signal"), + f.createToken( + ts.SyntaxKind.QuestionToken + ), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) + ), + ]), + undefined + ), + ], + undefined, + f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + f.createCallExpression( + f.createIdentifier(operationFetcherFnName), + undefined, + [ + f.createObjectLiteralExpression( + [ + f.createSpreadAssignment( + f.createIdentifier("variables") + ), + ], + false + ), + f.createIdentifier("signal"), + ] + ) + ) + ), + ], + true ), - ], - true + ] ) ) ), diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts index 7687f082..ee41d76d 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts @@ -90,7 +90,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -109,9 +109,31 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Get all the pets + */ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -175,7 +197,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -194,9 +216,22 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -204,9 +239,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -295,7 +329,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -327,9 +361,31 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Get all the pets + */ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -418,7 +474,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -450,9 +506,22 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -460,9 +529,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -537,7 +605,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -565,9 +633,31 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", variables }), - queryFn: ({ signal }) => fetchShowPetById({ ...fetcherOptions, ...variables }, signal), + export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets/{petId}", + operationId: "showPetById", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchShowPetById({ ...variables }, signal) + }); + + /** + * Info for a specific pet + */ + export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Info for a specific pet + */ + export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -643,7 +733,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -671,9 +761,22 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", variables }), - queryFn: ({ signal }) => fetchShowPetById({ ...fetcherOptions, ...variables }, signal), + export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets/{petId}", + operationId: "showPetById", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchShowPetById({ ...variables }, signal) + }); + + /** + * Info for a specific pet + */ + export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -681,9 +784,8 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ - queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", variables }), - queryFn: ({ signal }) => fetchShowPetById({ ...fetcherOptions, ...variables }, signal), + export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -773,7 +875,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -809,9 +911,31 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Get all the pets + */ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -889,7 +1013,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -908,9 +1032,31 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Get all the pets + */ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; @@ -1015,7 +1161,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1041,7 +1187,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "post", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1149,7 +1295,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1175,7 +1321,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "get", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1289,7 +1435,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1309,7 +1455,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "post", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1402,7 +1548,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1421,7 +1567,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1514,7 +1660,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1533,7 +1679,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1626,7 +1772,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1645,7 +1791,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = usePetstoreContext(); + const { fetcherOptions } = getPetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1738,7 +1884,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { useContext, Context } from "./context"; + import { getContext, Context } from "./context"; import type * as Fetcher from "./fetcher"; import { fetch } from "./fetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1757,7 +1903,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => fetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = useContext(); + const { fetcherOptions } = getContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1834,7 +1980,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { usePetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -1857,9 +2003,31 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { fetcherOptions, queryOptions, queryKeyFn } = usePetstoreContext(options); return reactQuery.useQuery({ - queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: ({ signal }) => fetchListPets({ ...fetcherOptions, ...variables }, signal), + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + queryKey: queryKeyFn({ + path: "/pets", + operationId: "listPets", + variables + }), + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => fetchListPets({ ...variables }, signal) + }); + + /** + * Get all the pets + */ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ + ...baseQuery, + ...options, + ...queryOptions + }); }; + + /** + * Get all the pets + */ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ + ...baseQuery, ...options, ...queryOptions }); }; diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.ts b/plugins/typescript/src/generators/generateReactQueryComponents.ts index 88d07972..4686cbc0 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.ts @@ -18,6 +18,7 @@ import { getContext } from "../templates/context"; import { getUtils } from "../templates/utils"; import { createNamespaceImport } from "../core/createNamespaceImport"; import { camelizedPathParams } from "../core/camelizedPathParams"; +import { createOperationQueryFnNodes } from "../core/createOperationQueryFnNodes"; export type Config = ConfigBase & { /** @@ -84,7 +85,7 @@ export const generateReactQueryComponents = async ( const fetcherFn = c.camel(`${filenamePrefix}-fetch`); const contextTypeName = `${c.pascal(filenamePrefix)}Context`; - const contextHookName = `use${c.pascal(filenamePrefix)}Context`; + const contextHookName = `get${c.pascal(filenamePrefix)}Context`; const nodes: ts.Node[] = []; const keyManagerItems: ts.TypeLiteralNode[] = []; @@ -153,6 +154,8 @@ export const generateReactQueryComponents = async ( nodes.push(...declarationNodes); const operationFetcherFnName = `fetch${c.pascal(operationId)}`; + const operationQueryFnName = `${c.camel(operationId)}Query`; + const component: "useQuery" | "useMutate" = operation["x-openapi-codegen-component"] || (verb === "get" ? "useQuery" : "useMutate"); @@ -215,23 +218,61 @@ export const generateReactQueryComponents = async ( url: route, verb, name: operationFetcherFnName, - }) + }), + ...(component === "useQuery" + ? [ + ...createOperationQueryFnNodes({ + operationFetcherFnName, + dataType, + errorType, + requestBodyType, + pathParamsType, + variablesType, + queryParamsType, + headersType, + operation, + operationId, + fetcherFn, + url: route, + verb, + name: operationQueryFnName, + }), + ...createQueryHook({ + operationFetcherFnName, + operationQueryFnName, + operation, + dataType, + errorType, + variablesType, + contextHookName, + name: `useSuspense${c.pascal(operationId)}`, + operationId, + url: route, + useQueryIdentifier: "useSuspenseQuery", + }), + ...createQueryHook({ + operationFetcherFnName, + operationQueryFnName, + operation, + dataType, + errorType, + variablesType, + contextHookName, + name: `use${c.pascal(operationId)}`, + operationId, + url: route, + }), + ] + : createMutationHook({ + operationFetcherFnName, + operation, + dataType, + errorType, + variablesType, + contextHookName, + name: `use${c.pascal(operationId)}`, + })) ); - - if (component === "useQuery") { - nodes.push(...createQueryHook(hookOptions)); - if (generateSuspenseQueries) { - nodes.push( - ...createQueryHook({ - ...hookOptions, - name: `useSuspense${c.pascal(operationId)}`, - useQueryIdentifier: "useSuspenseQuery", - }) - ); - } - } else { - nodes.push(...createMutationHook(hookOptions)); - } }); } ); @@ -454,6 +495,7 @@ const createMutationHook = ({ const createQueryHook = ({ operationFetcherFnName, + operationQueryFnName, contextHookName, dataType, errorType, @@ -465,6 +507,7 @@ const createQueryHook = ({ useQueryIdentifier = "useQuery", }: { operationFetcherFnName: string; + operationQueryFnName: string; contextHookName: string; name: string; operationId: string; @@ -523,24 +566,12 @@ const createQueryHook = ({ [ f.createVariableDeclaration( f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("fetcherOptions"), - undefined - ), f.createBindingElement( undefined, undefined, f.createIdentifier("queryOptions"), undefined ), - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("queryKeyFn"), - undefined - ), ]), undefined, undefined, @@ -554,6 +585,24 @@ const createQueryHook = ({ ts.NodeFlags.Const ) ), + f.createVariableStatement( + undefined, + f.createVariableDeclarationList( + [ + f.createVariableDeclaration( + f.createIdentifier("baseQuery"), + undefined, + undefined, + f.createCallExpression( + f.createIdentifier(operationQueryFnName), + undefined, + [f.createIdentifier("variables")] + ) + ), + ], + ts.NodeFlags.Const + ) + ), f.createReturnStatement( f.createCallExpression( f.createPropertyAccessExpression( @@ -571,71 +620,8 @@ const createQueryHook = ({ [ f.createObjectLiteralExpression( [ - f.createPropertyAssignment( - "queryKey", - f.createCallExpression( - f.createIdentifier("queryKeyFn"), - undefined, - [ - f.createObjectLiteralExpression([ - f.createPropertyAssignment( - "path", - f.createStringLiteral( - camelizedPathParams(url) - ) - ), - f.createPropertyAssignment( - "operationId", - f.createStringLiteral(operationId) - ), - f.createShorthandPropertyAssignment( - f.createIdentifier("variables") - ), - ]), - ] - ) - ), - f.createPropertyAssignment( - "queryFn", - f.createArrowFunction( - undefined, - undefined, - [ - f.createParameterDeclaration( - undefined, - undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - "signal" - ), - ]) - ), - ], - undefined, - f.createToken( - ts.SyntaxKind.EqualsGreaterThanToken - ), - f.createCallExpression( - f.createIdentifier(operationFetcherFnName), - undefined, - [ - f.createObjectLiteralExpression( - [ - f.createSpreadAssignment( - f.createIdentifier("fetcherOptions") - ), - f.createSpreadAssignment( - f.createIdentifier("variables") - ), - ], - false - ), - f.createIdentifier("signal"), - ] - ) - ) + f.createSpreadAssignment( + f.createIdentifier("baseQuery") ), f.createSpreadAssignment( f.createIdentifier("options") diff --git a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts index ac89ba0a..bc447955 100644 --- a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts @@ -109,18 +109,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); @@ -242,18 +237,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); @@ -357,18 +347,13 @@ describe("generateReactQueryFunctions", () => { /** * Info for a specific pet */ - export const showPetByIdQuery = (variables: ShowPetByIdVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchShowPetById({ ...variables }, signal) }); @@ -494,18 +479,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); @@ -602,18 +582,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); @@ -1211,18 +1186,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); @@ -1306,18 +1276,13 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables): { - queryKey: reactQuery.QueryKey; - queryFn: ({ signal }: { - signal?: AbortSignal; - }) => Promise; - } => ({ + export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", variables }), - queryFn: async ({ signal }: { + queryFn: ({ signal }: { signal?: AbortSignal; }) => fetchListPets({ ...variables }, signal) }); diff --git a/plugins/typescript/src/templates/context.ts b/plugins/typescript/src/templates/context.ts index 30b75fd0..17be651b 100644 --- a/plugins/typescript/src/templates/context.ts +++ b/plugins/typescript/src/templates/context.ts @@ -22,10 +22,6 @@ export const getContext = (prefix: string, componentsFile: string) => */ enabled?: boolean; }; - /** - * Query key manager. - */ - queryKeyFn: (operation: QueryOperation) => QueryKey; }; /** @@ -33,7 +29,7 @@ export const getContext = (prefix: string, componentsFile: string) => * * @param queryOptions options from the useQuery wrapper */ - export function use${pascal(prefix)}Context< + export function get${pascal(prefix)}Context< TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, @@ -43,8 +39,7 @@ export const getContext = (prefix: string, componentsFile: string) => ): ${pascal(prefix)}Context { return { fetcherOptions: {}, - queryOptions: {}, - queryKeyFn + queryOptions: {} } }; From 80577090f289dd8919be13fb515d6a59789a554b Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Thu, 21 Nov 2024 14:38:35 +0100 Subject: [PATCH 2/8] fixes --- package-lock.json | 2 +- .../src/core/createOperationQueryFnNodes.ts | 314 +++++++++++------- .../generateReactQueryComponents.test.ts | 116 ++++--- .../generateReactQueryComponents.ts | 26 +- .../generateReactQueryFunctions.test.ts | 49 ++- 5 files changed, 317 insertions(+), 190 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3dfe4bdc..e1b133da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ }, "cli": { "name": "@openapi-codegen/cli", - "version": "2.0.4", + "version": "3.0.1", "license": "MIT", "dependencies": { "@clack/prompts": "^0.9.1", diff --git a/plugins/typescript/src/core/createOperationQueryFnNodes.ts b/plugins/typescript/src/core/createOperationQueryFnNodes.ts index fa5ac2fb..7413eae5 100644 --- a/plugins/typescript/src/core/createOperationQueryFnNodes.ts +++ b/plugins/typescript/src/core/createOperationQueryFnNodes.ts @@ -66,145 +66,221 @@ export const createOperationQueryFnNodes = ({ undefined ), ], - undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("queryKey"), + undefined, + f.createTypeReferenceNode( + f.createQualifiedName( + f.createIdentifier("reactQuery"), + f.createIdentifier("QueryKey") + ), + undefined + ) + ), + f.createPropertySignature( + undefined, + f.createIdentifier("queryFn"), + undefined, + f.createFunctionTypeNode( + undefined, + verb === "get" + ? [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("signal"), + undefined + ), + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("signal"), + f.createToken(ts.SyntaxKind.QuestionToken), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) + ), + ]), + undefined + ), + ] + : [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("variables"), + undefined + ), + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("signal"), + undefined + ), + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("variables"), + undefined, + variablesType + ), + f.createPropertySignature( + undefined, + f.createIdentifier("signal"), + f.createToken(ts.SyntaxKind.QuestionToken), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) + ), + ]), + undefined + ), + ], + f.createTypeReferenceNode(f.createIdentifier("Promise"), [ + dataType, + ]) + ) + ), + ]), f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - f.createCallExpression( - f.createPropertyAccessExpression( - f.createIdentifier("reactQuery"), - f.createIdentifier("queryOptions") - ), - undefined, + f.createObjectLiteralExpression( [ - f.createObjectLiteralExpression( - [ - f.createPropertyAssignment( - f.createIdentifier("queryKey"), - f.createCallExpression( - f.createIdentifier("queryKeyFn"), - undefined, + f.createPropertyAssignment( + f.createIdentifier("queryKey"), + f.createCallExpression( + f.createIdentifier("queryKeyFn"), + undefined, + [ + f.createObjectLiteralExpression( [ - f.createObjectLiteralExpression( - [ - f.createPropertyAssignment( - f.createIdentifier("path"), - f.createStringLiteral( - camelizedPathParams(url) - ) - ), - f.createPropertyAssignment( - f.createIdentifier("operationId"), - f.createStringLiteral(operationId) - ), - f.createShorthandPropertyAssignment( - f.createIdentifier("variables"), + f.createPropertyAssignment( + f.createIdentifier("path"), + f.createStringLiteral(camelizedPathParams(url)) + ), + f.createPropertyAssignment( + f.createIdentifier("operationId"), + f.createStringLiteral(operationId) + ), + f.createShorthandPropertyAssignment( + f.createIdentifier("variables"), + undefined + ), + ], + true + ), + ] + ) + ), + f.createPropertyAssignment( + f.createIdentifier("queryFn"), + f.createArrowFunction( + undefined, + undefined, + verb === "get" + ? [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, + undefined, + f.createIdentifier("signal"), undefined ), - ], - true + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( + undefined, + f.createIdentifier("signal"), + f.createToken(ts.SyntaxKind.QuestionToken), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) + ), + ]), + undefined ), ] - ) - ), - f.createPropertyAssignment( - f.createIdentifier("queryFn"), - f.createArrowFunction( - undefined, - undefined, - verb === "get" - ? [ - f.createParameterDeclaration( + : [ + f.createParameterDeclaration( + undefined, + undefined, + f.createObjectBindingPattern([ + f.createBindingElement( + undefined, undefined, + f.createIdentifier("variables"), + undefined + ), + f.createBindingElement( undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken( - ts.SyntaxKind.QuestionToken - ), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), + f.createIdentifier("signal"), undefined ), - ] - : [ - f.createParameterDeclaration( + ]), + undefined, + f.createTypeLiteralNode([ + f.createPropertySignature( undefined, + f.createIdentifier("variables"), undefined, - f.createObjectBindingPattern([ - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("variables"), - undefined - ), - f.createBindingElement( - undefined, - undefined, - f.createIdentifier("signal"), - undefined - ), - ]), + variablesType + ), + f.createPropertySignature( undefined, - f.createTypeLiteralNode([ - f.createPropertySignature( - undefined, - f.createIdentifier("variables"), - undefined, - variablesType - ), - f.createPropertySignature( - undefined, - f.createIdentifier("signal"), - f.createToken( - ts.SyntaxKind.QuestionToken - ), - f.createTypeReferenceNode( - f.createIdentifier("AbortSignal"), - undefined - ) - ), - ]), - undefined + f.createIdentifier("signal"), + f.createToken(ts.SyntaxKind.QuestionToken), + f.createTypeReferenceNode( + f.createIdentifier("AbortSignal"), + undefined + ) ), - ], - undefined, - f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - f.createCallExpression( - f.createIdentifier(operationFetcherFnName), - undefined, + ]), + undefined + ), + ], + undefined, + f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + f.createCallExpression( + f.createIdentifier(operationFetcherFnName), + undefined, + [ + f.createObjectLiteralExpression( [ - f.createObjectLiteralExpression( - [ - f.createSpreadAssignment( - f.createIdentifier("variables") - ), - ], - false + f.createSpreadAssignment( + f.createIdentifier("variables") ), - f.createIdentifier("signal"), - ] - ) - ) - ), - ], - true + ], + false + ), + f.createIdentifier("signal"), + ] + ) + ) ), - ] + ], + true ) ) ), diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts index ee41d76d..728dba71 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts @@ -90,7 +90,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -109,7 +109,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -123,8 +128,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -132,8 +137,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -329,7 +334,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -361,7 +366,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -375,8 +385,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -384,8 +394,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -605,7 +615,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -633,7 +643,12 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ + export const showPetByIdQuery = (variables: ShowPetByIdVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", @@ -647,8 +662,8 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...showPetByIdQuery(variables), ...options, ...queryOptions }); }; @@ -656,8 +671,8 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...showPetByIdQuery(variables), ...options, ...queryOptions }); }; @@ -875,7 +890,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -911,7 +926,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -925,8 +945,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -934,8 +954,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -1013,7 +1033,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -1032,7 +1052,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -1046,8 +1071,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -1055,8 +1080,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -1161,7 +1186,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1295,7 +1320,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1435,7 +1460,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1548,7 +1573,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1660,7 +1685,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1772,7 +1797,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1884,7 +1909,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getContext, Context } from "./context"; + import { getContext, Context, queryKeyFn } from "./context"; import type * as Fetcher from "./fetcher"; import { fetch } from "./fetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1980,7 +2005,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -2003,7 +2028,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -2017,8 +2047,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -2026,8 +2056,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.ts b/plugins/typescript/src/generators/generateReactQueryComponents.ts index 4686cbc0..9b20bac6 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.ts @@ -326,7 +326,7 @@ export const generateReactQueryComponents = async ( createWatermark(context.openAPIDocument.info), createReactQueryImport(), createNamedImport( - [contextHookName, contextTypeName], + [contextHookName, contextTypeName, "queryKeyFn"], `./${contextFilename}` ), createNamespaceImport("Fetcher", `./${fetcherFilename}`), @@ -585,24 +585,6 @@ const createQueryHook = ({ ts.NodeFlags.Const ) ), - f.createVariableStatement( - undefined, - f.createVariableDeclarationList( - [ - f.createVariableDeclaration( - f.createIdentifier("baseQuery"), - undefined, - undefined, - f.createCallExpression( - f.createIdentifier(operationQueryFnName), - undefined, - [f.createIdentifier("variables")] - ) - ), - ], - ts.NodeFlags.Const - ) - ), f.createReturnStatement( f.createCallExpression( f.createPropertyAccessExpression( @@ -621,7 +603,11 @@ const createQueryHook = ({ f.createObjectLiteralExpression( [ f.createSpreadAssignment( - f.createIdentifier("baseQuery") + f.createCallExpression( + f.createIdentifier(operationQueryFnName), + undefined, + [f.createIdentifier("variables")] + ) ), f.createSpreadAssignment( f.createIdentifier("options") diff --git a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts index bc447955..ac576d73 100644 --- a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts @@ -109,7 +109,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -237,7 +242,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -347,7 +357,12 @@ describe("generateReactQueryFunctions", () => { /** * Info for a specific pet */ - export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ + export const showPetByIdQuery = (variables: ShowPetByIdVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", @@ -479,7 +494,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -582,7 +602,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -1186,7 +1211,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -1276,7 +1306,12 @@ describe("generateReactQueryFunctions", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", From 68cc551af9e9963c08ca6a486590dc0cfeb30bae Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Thu, 21 Nov 2024 14:57:01 +0100 Subject: [PATCH 3/8] fix camel case difference from 'case' and 'lodash' --- .../typescript/src/generators/generateReactQueryComponents.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.ts b/plugins/typescript/src/generators/generateReactQueryComponents.ts index 9b20bac6..ae28a743 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.ts @@ -1,6 +1,6 @@ import ts, { factory as f } from "typescript"; import * as c from "case"; -import { get } from "lodash"; +import { get, camelCase } from "lodash"; import { ConfigBase, Context } from "./types"; import { OperationObject, PathItemObject } from "openapi3-ts"; @@ -154,7 +154,7 @@ export const generateReactQueryComponents = async ( nodes.push(...declarationNodes); const operationFetcherFnName = `fetch${c.pascal(operationId)}`; - const operationQueryFnName = `${c.camel(operationId)}Query`; + const operationQueryFnName = camelCase(`${c.camel(operationId)}Query`); const component: "useQuery" | "useMutate" = operation["x-openapi-codegen-component"] || From 6831a6af514c1774a4ab61bba0fa902065ffe7fb Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Thu, 21 Nov 2024 14:59:25 +0100 Subject: [PATCH 4/8] revert name change --- .../generateReactQueryComponents.test.ts | 64 +++++++++---------- .../generateReactQueryComponents.ts | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts index 728dba71..4d3b0a42 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts @@ -90,7 +90,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -128,7 +128,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -137,7 +137,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -334,7 +334,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -385,7 +385,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -394,7 +394,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -615,7 +615,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -662,7 +662,7 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...showPetByIdQuery(variables), ...options, ...queryOptions @@ -671,7 +671,7 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...showPetByIdQuery(variables), ...options, ...queryOptions @@ -890,7 +890,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -945,7 +945,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -954,7 +954,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -1033,7 +1033,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -1071,7 +1071,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -1080,7 +1080,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -1186,7 +1186,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1212,7 +1212,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "post", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1320,7 +1320,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; @@ -1346,7 +1346,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "get", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1460,7 +1460,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1480,7 +1480,7 @@ describe("generateReactQueryComponents", () => { export const fetchAddPet = (variables: AddPetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet", method: "post", ...variables, signal }); export const useAddPet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: AddPetVariables) => fetchAddPet({ ...fetcherOptions, ...variables }), ...options @@ -1573,7 +1573,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1592,7 +1592,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1685,7 +1685,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1704,7 +1704,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1797,7 +1797,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1816,7 +1816,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => petstoreFetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getPetstoreContext(); + const { fetcherOptions } = usePetstoreContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -1909,7 +1909,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getContext, Context, queryKeyFn } from "./context"; + import { useContext, Context, queryKeyFn } from "./context"; import type * as Fetcher from "./fetcher"; import { fetch } from "./fetcher"; import type * as RequestBodies from "./petstoreRequestBodies"; @@ -1928,7 +1928,7 @@ describe("generateReactQueryComponents", () => { export const fetchUpdatePet = (variables: UpdatePetVariables, signal?: AbortSignal) => fetch({ url: "/pet/{petId}", method: "put", ...variables, signal }); export const useUpdatePet = (options?: Omit, "mutationFn">) => { - const { fetcherOptions } = getContext(); + const { fetcherOptions } = useContext(); return reactQuery.useMutation({ mutationFn: (variables: UpdatePetVariables) => fetchUpdatePet({ ...fetcherOptions, ...variables }), ...options @@ -2005,7 +2005,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -2047,7 +2047,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useSuspenseQuery({ + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ ...listPetsQuery(variables), ...options, ...queryOptions @@ -2056,7 +2056,7 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); return reactQuery.useQuery({ + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ ...listPetsQuery(variables), ...options, ...queryOptions diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.ts b/plugins/typescript/src/generators/generateReactQueryComponents.ts index ae28a743..5bf8ddf6 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.ts @@ -85,7 +85,7 @@ export const generateReactQueryComponents = async ( const fetcherFn = c.camel(`${filenamePrefix}-fetch`); const contextTypeName = `${c.pascal(filenamePrefix)}Context`; - const contextHookName = `get${c.pascal(filenamePrefix)}Context`; + const contextHookName = `use${c.pascal(filenamePrefix)}Context`; const nodes: ts.Node[] = []; const keyManagerItems: ts.TypeLiteralNode[] = []; From 26ede5b0d3b5a75199924aa0ac3d2126d6388663 Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Thu, 21 Nov 2024 15:00:29 +0100 Subject: [PATCH 5/8] revert context name --- plugins/typescript/src/templates/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/typescript/src/templates/context.ts b/plugins/typescript/src/templates/context.ts index 17be651b..795a8a1d 100644 --- a/plugins/typescript/src/templates/context.ts +++ b/plugins/typescript/src/templates/context.ts @@ -29,7 +29,7 @@ export const getContext = (prefix: string, componentsFile: string) => * * @param queryOptions options from the useQuery wrapper */ - export function get${pascal(prefix)}Context< + export function use${pascal(prefix)}Context< TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, From 87822707cce49e4d9cd40f2809f479ce0c7182e8 Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Tue, 21 Jan 2025 14:30:27 +0100 Subject: [PATCH 6/8] fix tests --- .../generateReactQueryComponents.test.ts | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts index 4d3b0a42..807fe3d5 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts @@ -202,7 +202,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -221,7 +221,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -235,8 +240,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -244,8 +249,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -484,7 +489,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -516,7 +521,12 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const listPetsQuery = (variables: ListPetsVariables) => reactQuery.queryOptions({ + export const listPetsQuery = (variables: ListPetsVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets", operationId: "listPets", @@ -530,8 +540,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -539,8 +549,8 @@ describe("generateReactQueryComponents", () => { /** * Get all the pets */ - export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = listPetsQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useListPets = (variables: ListPetsVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ + ...listPetsQuery(variables), ...options, ...queryOptions }); }; @@ -748,7 +758,7 @@ describe("generateReactQueryComponents", () => { * @version 1.0.0 */ import * as reactQuery from "@tanstack/react-query"; - import { getPetstoreContext, PetstoreContext } from "./petstoreContext"; + import { usePetstoreContext, PetstoreContext, queryKeyFn } from "./petstoreContext"; import type * as Fetcher from "./petstoreFetcher"; import { petstoreFetch } from "./petstoreFetcher"; import type * as Schemas from "./petstoreSchemas"; @@ -776,7 +786,12 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const showPetByIdQuery = (variables: ShowPetByIdVariables) => reactQuery.queryOptions({ + export const showPetByIdQuery = (variables: ShowPetByIdVariables): { + queryKey: reactQuery.QueryKey; + queryFn: ({ signal }: { + signal?: AbortSignal; + }) => Promise; + } => ({ queryKey: queryKeyFn({ path: "/pets/{petId}", operationId: "showPetById", @@ -790,8 +805,8 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useSuspenseQuery({ - ...baseQuery, + export const useSuspenseShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useSuspenseQuery({ + ...showPetByIdQuery(variables), ...options, ...queryOptions }); }; @@ -799,8 +814,8 @@ describe("generateReactQueryComponents", () => { /** * Info for a specific pet */ - export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = getPetstoreContext(options); const baseQuery = showPetByIdQuery(variables); return reactQuery.useQuery({ - ...baseQuery, + export const useShowPetById = (variables: ShowPetByIdVariables, options?: Omit, "queryKey" | "queryFn" | "initialData">) => { const { queryOptions } = usePetstoreContext(options); return reactQuery.useQuery({ + ...showPetByIdQuery(variables), ...options, ...queryOptions }); }; From de55bb974279df15caf789152f96f4ce61f9ecb7 Mon Sep 17 00:00:00 2001 From: "jan.silhan" Date: Tue, 21 Jan 2025 14:49:11 +0100 Subject: [PATCH 7/8] small fixes --- plugins/typescript/README.md | 6 ---- .../src/core/createOperationQueryFnNodes.ts | 9 +---- .../generateReactQueryComponents.test.ts | 24 +++++++------- .../generateReactQueryComponents.ts | 33 +++---------------- .../generateReactQueryFunctions.test.ts | 14 ++++---- 5 files changed, 25 insertions(+), 61 deletions(-) diff --git a/plugins/typescript/README.md b/plugins/typescript/README.md index 6dd07507..fc6b0e4a 100644 --- a/plugins/typescript/README.md +++ b/plugins/typescript/README.md @@ -2,12 +2,6 @@ Collection of typescript generators & utils -## Options - -### generateSuspenseQueries - -Generate `useSuspenseQuery` wrapper along side `useQuery`. - ## Generators ### generateSchemaType diff --git a/plugins/typescript/src/core/createOperationQueryFnNodes.ts b/plugins/typescript/src/core/createOperationQueryFnNodes.ts index 7413eae5..7b176c5e 100644 --- a/plugins/typescript/src/core/createOperationQueryFnNodes.ts +++ b/plugins/typescript/src/core/createOperationQueryFnNodes.ts @@ -266,14 +266,7 @@ export const createOperationQueryFnNodes = ({ f.createIdentifier(operationFetcherFnName), undefined, [ - f.createObjectLiteralExpression( - [ - f.createSpreadAssignment( - f.createIdentifier("variables") - ), - ], - false - ), + f.createIdentifier("variables"), f.createIdentifier("signal"), ] ) diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts index 807fe3d5..08045485 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.test.ts @@ -122,7 +122,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -191,7 +191,7 @@ describe("generateReactQueryComponents", () => { existsFile: () => true, readFile: async () => "", }, - { ...config, generateSuspenseQueries: true }, + { ...config }, ); expect(writeFile.mock.calls[0][0]).toBe("petstoreComponents.ts"); @@ -234,7 +234,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -384,7 +384,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -478,7 +478,7 @@ describe("generateReactQueryComponents", () => { existsFile: () => true, readFile: async () => "", }, - { ...config, generateSuspenseQueries: true }, + { ...config }, ); expect(writeFile.mock.calls[0][0]).toBe("petstoreComponents.ts"); @@ -534,7 +534,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -666,7 +666,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchShowPetById({ ...variables }, signal) + }) => fetchShowPetById(variables, signal) }); /** @@ -747,7 +747,7 @@ describe("generateReactQueryComponents", () => { existsFile: () => true, readFile: async () => "", }, - { ...config, generateSuspenseQueries: true }, + { ...config }, ); expect(writeFile.mock.calls[0][0]).toBe("petstoreComponents.ts"); @@ -799,7 +799,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchShowPetById({ ...variables }, signal) + }) => fetchShowPetById(variables, signal) }); /** @@ -954,7 +954,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -1080,7 +1080,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** @@ -2056,7 +2056,7 @@ describe("generateReactQueryComponents", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); /** diff --git a/plugins/typescript/src/generators/generateReactQueryComponents.ts b/plugins/typescript/src/generators/generateReactQueryComponents.ts index 5bf8ddf6..b7d37ed2 100644 --- a/plugins/typescript/src/generators/generateReactQueryComponents.ts +++ b/plugins/typescript/src/generators/generateReactQueryComponents.ts @@ -36,12 +36,6 @@ export type Config = ConfigBase & { * This will mark the header as optional in the component API */ injectedHeaders?: string[]; - /** - * Generate React Query components with `useSuspenseQuery` hook. - * - * @default false - */ - generateSuspenseQueries?: boolean; }; export const generateReactQueryComponents = async ( @@ -81,8 +75,6 @@ export const generateReactQueryComponents = async ( const filename = formatFilename(filenamePrefix + "-components"); - const { generateSuspenseQueries = false } = config; - const fetcherFn = c.camel(`${filenamePrefix}-fetch`); const contextTypeName = `${c.pascal(filenamePrefix)}Context`; const contextHookName = `use${c.pascal(filenamePrefix)}Context`; @@ -192,16 +184,17 @@ export const generateReactQueryComponents = async ( ); } - const hookOptions = { + const useQueryHookOptions = { operationFetcherFnName, + operationQueryFnName, operation, dataType, errorType, variablesType, contextHookName, - name: `use${c.pascal(operationId)}`, operationId, url: route, + name: `use${c.pascal(operationId)}`, }; nodes.push( @@ -238,29 +231,13 @@ export const generateReactQueryComponents = async ( name: operationQueryFnName, }), ...createQueryHook({ - operationFetcherFnName, - operationQueryFnName, - operation, - dataType, - errorType, - variablesType, - contextHookName, + ...useQueryHookOptions, name: `useSuspense${c.pascal(operationId)}`, - operationId, - url: route, useQueryIdentifier: "useSuspenseQuery", }), ...createQueryHook({ - operationFetcherFnName, - operationQueryFnName, - operation, - dataType, - errorType, - variablesType, - contextHookName, + ...useQueryHookOptions, name: `use${c.pascal(operationId)}`, - operationId, - url: route, }), ] : createMutationHook({ diff --git a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts index ac576d73..2b9db15f 100644 --- a/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts +++ b/plugins/typescript/src/generators/generateReactQueryFunctions.test.ts @@ -122,7 +122,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { @@ -255,7 +255,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { @@ -370,7 +370,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchShowPetById({ ...variables }, signal) + }) => fetchShowPetById(variables, signal) }); export type QueryOperation = { @@ -507,7 +507,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { @@ -615,7 +615,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { @@ -1224,7 +1224,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { @@ -1319,7 +1319,7 @@ describe("generateReactQueryFunctions", () => { }), queryFn: ({ signal }: { signal?: AbortSignal; - }) => fetchListPets({ ...variables }, signal) + }) => fetchListPets(variables, signal) }); export type QueryOperation = { From af41d2259791365d6715e41d49b9d71ad49a0f12 Mon Sep 17 00:00:00 2001 From: Fabien Bernard Date: Thu, 30 Jan 2025 19:09:29 +0100 Subject: [PATCH 8/8] Update context template with the correct types --- plugins/typescript/src/templates/context.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/plugins/typescript/src/templates/context.ts b/plugins/typescript/src/templates/context.ts index 795a8a1d..c00c2cee 100644 --- a/plugins/typescript/src/templates/context.ts +++ b/plugins/typescript/src/templates/context.ts @@ -1,10 +1,20 @@ import { pascal } from "case"; export const getContext = (prefix: string, componentsFile: string) => - `import type { QueryKey, UseQueryOptions } from "@tanstack/react-query"; + `import type { + DefaultError, + Enabled, + QueryKey, + UseQueryOptions, + } from "@tanstack/react-query"; import { QueryOperation } from './${componentsFile}'; - export type ${pascal(prefix)}Context = { + export type ${pascal(prefix)}Context< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = { fetcherOptions: { /** * Headers to inject in the fetcher @@ -20,7 +30,7 @@ export const getContext = (prefix: string, componentsFile: string) => * Set this to \`false\` to disable automatic refetching when the query mounts or changes query keys. * Defaults to \`true\`. */ - enabled?: boolean; + enabled?: Enabled; }; }; @@ -31,12 +41,12 @@ export const getContext = (prefix: string, componentsFile: string) => */ export function use${pascal(prefix)}Context< TQueryFnData = unknown, - TError = unknown, + TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey >( _queryOptions?: Omit, 'queryKey' | 'queryFn'> - ): ${pascal(prefix)}Context { + ): ${pascal(prefix)}Context { return { fetcherOptions: {}, queryOptions: {} @@ -61,6 +71,7 @@ export const getContext = (prefix: string, componentsFile: string) => return queryKey; } + // Helpers const resolvePathParam = ( key: string,