@kubb/plugin-react-query
Version:
React Query hooks generator plugin for Kubb, creating type-safe API client hooks from OpenAPI specifications for React applications.
1,427 lines (1,426 loc) • 48.3 kB
JavaScript
import "./chunk--u3MIqq1.js";
import { a as Mutation, c as InfiniteQuery, d as MutationKey, i as Query, l as QueryOptions, n as SuspenseInfiniteQueryOptions, o as MutationOptions, r as SuspenseInfiniteQuery, s as InfiniteQueryOptions, t as SuspenseQuery, u as QueryKey } from "./components-CpyHYGOw.js";
import path from "node:path";
import fs from "node:fs";
import { pluginClientName } from "@kubb/plugin-client";
import { pluginTsName } from "@kubb/plugin-ts";
import { pluginZodName } from "@kubb/plugin-zod";
import { getBanner, getFooter } from "@kubb/plugin-oas/utils";
import { File, Function, Type } from "@kubb/react-fabric";
import { Fragment, jsx, jsxs } from "@kubb/react-fabric/jsx-runtime";
import { Client } from "@kubb/plugin-client/components";
import { usePluginManager } from "@kubb/core/hooks";
import { createReactGenerator } from "@kubb/plugin-oas/generators";
import { useOas, useOperationManager } from "@kubb/plugin-oas/hooks";
import { difference } from "remeda";
//#region src/generators/customHookOptionsFileGenerator.tsx
const customHookOptionsFileGenerator = createReactGenerator({
name: "react-query-custom-hook-options-file",
Operations({ operations, generator, plugin, config }) {
const { options, options: { output }, key: pluginKey } = plugin;
const pluginManager = usePluginManager();
const { getFile } = useOperationManager(generator);
if (!options.customOptions) return null;
const override = output.override ?? config.output.override ?? false;
const { importPath, name } = options.customOptions;
const root = path.resolve(config.root, config.output.path);
const reactQueryImportPath = options.query ? options.query.importPath : "@tanstack/react-query";
const getHookFilePath = (operations) => {
const firstOperation = operations[0];
if (firstOperation != null) return getFile(firstOperation, { prefix: "use" }).path;
return pluginManager.getFile({
name: "index",
extname: ".ts",
pluginKey
}).path;
};
const ensureExtension = (filePath, extname) => {
if (path.extname(filePath) === "") return filePath + extname;
return filePath;
};
const getExternalFile = (filePath, rootPath) => {
const actualFilePath = ensureExtension(filePath, ".ts");
return {
baseName: path.basename(actualFilePath),
name: path.basename(actualFilePath, path.extname(actualFilePath)),
path: path.resolve(rootPath, actualFilePath)
};
};
const file = getExternalFile(importPath, path.dirname(getHookFilePath(operations)));
if (fs.existsSync(file.path) && !override) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: file.baseName,
path: file.path,
children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["QueryClient"],
path: reactQueryImportPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["useQueryClient"],
path: reactQueryImportPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["HookOptions"],
root: file.path,
path: path.resolve(root, "./index.ts")
}),
/* @__PURE__ */ jsxs(File.Source, {
name: file.name,
isExportable: true,
isIndexable: true,
children: [/* @__PURE__ */ jsx(Function, {
name: "getCustomHookOptions",
params: "{ queryClient }: { queryClient: QueryClient }",
returnType: "Partial<HookOptions>",
children: `return {
// TODO: Define custom hook options here
// Example:
// useUpdatePetHook: {
// onSuccess: () => {
// void queryClient.invalidateQueries({ queryKey: ['pet'] })
// }
// }
}`
}), /* @__PURE__ */ jsx(Function, {
name,
generics: "T extends keyof HookOptions",
params: "{ hookName, operationId }: { hookName: T, operationId: string }",
returnType: "HookOptions[T]",
export: true,
children: `const queryClient = useQueryClient()
const customOptions = getCustomHookOptions({ queryClient })
return customOptions[hookName] ?? {}`
})]
})
]
});
}
});
//#endregion
//#region src/generators/hookOptionsGenerator.tsx
const hookOptionsGenerator = createReactGenerator({
name: "react-query-hook-options",
Operations({ operations, plugin, generator }) {
const { options, options: { output }, key: pluginKey } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getName, getFile } = useOperationManager(generator);
if (!options.customOptions) return null;
const name = "HookOptions";
const file = pluginManager.getFile({
name,
extname: ".ts",
pluginKey
});
const getOperationOptions = (operation) => {
const operationOptions = generator.getOptions(operation, operation.method);
return {
...options,
...operationOptions
};
};
const isQuery = (operation) => {
const operationOptions = getOperationOptions(operation);
return typeof operationOptions.query === "boolean" ? true : operationOptions.query?.methods.some((method) => operation.method === method);
};
const isMutation = (operation) => {
const operationOptions = getOperationOptions(operation);
return operationOptions.mutation !== false && !isQuery(operation) && difference(operationOptions.mutation ? operationOptions.mutation.methods : [], operationOptions.query ? operationOptions.query.methods : []).some((method) => operation.method === method);
};
const isSuspense = (operation) => {
return !!getOperationOptions(operation).suspense;
};
const isInfinite = (operation) => {
const operationOptions = getOperationOptions(operation);
return !!(operationOptions.infinite && typeof operationOptions.infinite === "object" ? operationOptions.infinite : void 0);
};
const getHookName = (operation) => {
return getName(operation, {
type: "function",
prefix: "use"
});
};
const getHookFile = (operation) => {
return getFile(operation, { prefix: "use" });
};
const getQueryHookOptions = (operation) => {
return getName(operation, {
type: "function",
suffix: "QueryOptions"
});
};
const getQueryHookOptionsImport = (operation) => {
return /* @__PURE__ */ jsx(File.Import, {
name: [getQueryHookOptions(operation)],
root: file.path,
path: getHookFile(operation).path
});
};
const getMutationHookOptions = (operation) => {
return getName(operation, {
type: "function",
suffix: "MutationOptions"
});
};
const getMutationHookOptionsImport = (operation) => {
return /* @__PURE__ */ jsx(File.Import, {
name: [getMutationHookOptions(operation)],
root: file.path,
path: getHookFile(operation).path
});
};
const getSuspenseHookName = (operation) => {
return getName(operation, {
type: "function",
prefix: "use",
suffix: "suspense"
});
};
const getSuspenseHookFile = (operation) => {
return getFile(operation, {
prefix: "use",
suffix: "suspense"
});
};
const getSuspenseHookOptions = (operation) => {
return getName(operation, {
type: "function",
suffix: "SuspenseQueryOptions"
});
};
const getSuspenseHookOptionsImport = (operation) => {
return /* @__PURE__ */ jsx(File.Import, {
name: [getSuspenseHookOptions(operation)],
root: file.path,
path: getSuspenseHookFile(operation).path
});
};
const getInfiniteHookName = (operation) => {
return getName(operation, {
type: "function",
prefix: "use",
suffix: "infinite"
});
};
const getInfiniteHookFile = (operation) => {
return getFile(operation, {
prefix: "use",
suffix: "infinite"
});
};
const getInfiniteHookOptions = (operation) => {
return getName(operation, {
type: "function",
suffix: "InfiniteQueryOptions"
});
};
const getInfiniteHookOptionsImport = (operation) => {
return /* @__PURE__ */ jsx(File.Import, {
name: [getInfiniteHookOptions(operation)],
root: file.path,
path: getInfiniteHookFile(operation).path
});
};
const getSuspenseInfiniteHookName = (operation) => {
return getName(operation, {
type: "function",
prefix: "use",
suffix: "suspenseInfinite"
});
};
const getSuspenseInfiniteHookFile = (operation) => {
return getFile(operation, {
prefix: "use",
suffix: "suspenseInfinite"
});
};
const getSuspenseInfiniteHookOptions = (operation) => {
return getName(operation, {
type: "function",
suffix: "SuspenseInfiniteQueryOptions"
});
};
const getSuspenseInfiniteHookOptionsImport = (operation) => {
return /* @__PURE__ */ jsx(File.Import, {
name: [getSuspenseInfiniteHookOptions(operation)],
root: file.path,
path: getSuspenseInfiniteHookFile(operation).path
});
};
const imports = operations.flatMap((operation) => {
if (isQuery(operation)) return [
getQueryHookOptionsImport(operation),
isSuspense(operation) ? getSuspenseHookOptionsImport(operation) : void 0,
isInfinite(operation) ? getInfiniteHookOptionsImport(operation) : void 0,
isSuspense(operation) && isInfinite(operation) ? getSuspenseInfiniteHookOptionsImport(operation) : void 0
].filter(Boolean);
if (isMutation(operation)) return [getMutationHookOptionsImport(operation)];
return [];
}).filter(Boolean);
const hookOptions = operations.reduce((acc, operation) => {
if (isQuery(operation)) {
acc[getHookName(operation)] = `Partial<ReturnType<typeof ${getQueryHookOptions(operation)}>>`;
if (isSuspense(operation)) acc[getSuspenseHookName(operation)] = `Partial<ReturnType<typeof ${getSuspenseHookOptions(operation)}>>`;
if (isInfinite(operation)) acc[getInfiniteHookName(operation)] = `Partial<ReturnType<typeof ${getInfiniteHookOptions(operation)}>>`;
if (isSuspense(operation) && isInfinite(operation)) acc[getSuspenseInfiniteHookName(operation)] = `Partial<ReturnType<typeof ${getSuspenseInfiniteHookOptions(operation)}>>`;
}
if (isMutation(operation)) acc[getHookName(operation)] = `Partial<ReturnType<typeof ${getMutationHookOptions(operation)}>>`;
return acc;
}, {});
return /* @__PURE__ */ jsxs(File, {
baseName: file.baseName,
path: file.path,
meta: file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [imports, /* @__PURE__ */ jsx(File.Source, {
name,
isExportable: true,
isIndexable: true,
isTypeOnly: true,
children: /* @__PURE__ */ jsx(Type, {
export: true,
name,
children: `{ ${Object.keys(hookOptions).map((key) => `${JSON.stringify(key)}: ${hookOptions[key]}`)} }`
})
})]
});
}
});
//#endregion
//#region src/generators/infiniteQueryGenerator.tsx
const infiniteQueryGenerator = createReactGenerator({
name: "react-infinite-query",
Operation({ config, operation, generator, plugin }) {
const { options, options: { output } } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getSchemas, getName, getFile } = useOperationManager(generator);
const isQuery = typeof options.query === "boolean" ? true : options.query?.methods.some((method) => operation.method === method);
const isMutation = difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
const infiniteOptions = options.infinite && typeof options.infinite === "object" ? options.infinite : void 0;
const importPath = options.query ? options.query.importPath : "@tanstack/react-query";
const query = {
name: getName(operation, {
type: "function",
prefix: "use",
suffix: "infinite"
}),
typeName: getName(operation, { type: "type" }),
file: getFile(operation, {
prefix: "use",
suffix: "infinite"
})
};
const shouldUseClientPlugin = !!pluginManager.getPluginByKey([pluginClientName]) && options.client.clientType !== "class";
const client = {
name: shouldUseClientPlugin ? getName(operation, {
type: "function",
pluginKey: [pluginClientName]
}) : getName(operation, {
type: "function",
suffix: "infinite"
}),
file: getFile(operation, { pluginKey: [pluginClientName] })
};
const queryOptions = { name: getName(operation, {
type: "function",
suffix: "InfiniteQueryOptions"
}) };
const queryKey = {
name: getName(operation, {
type: "const",
suffix: "InfiniteQueryKey"
}),
typeName: getName(operation, {
type: "type",
suffix: "InfiniteQueryKey"
})
};
const type = {
file: getFile(operation, { pluginKey: [pluginTsName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginTsName],
type: "type"
})
};
const zod = {
file: getFile(operation, { pluginKey: [pluginZodName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginZodName],
type: "function"
})
};
if (!isQuery || isMutation || !infiniteOptions) return null;
const normalizeKey = (key) => (key ?? "").replace(/\?$/, "");
const queryParam = infiniteOptions.queryParam;
const cursorParam = infiniteOptions.cursorParam;
const queryParamKeys = type.schemas.queryParams?.keys ?? [];
const responseKeys = [...type.schemas.responses?.flatMap((item) => item.keys ?? []) ?? [], ...type.schemas.response?.keys ?? []];
const hasQueryParam = queryParam ? queryParamKeys.some((key) => normalizeKey(key) === queryParam) : false;
const hasCursorParam = cursorParam ? responseKeys.some((key) => normalizeKey(key) === cursorParam) : true;
if (!hasQueryParam || !hasCursorParam) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: query.file.baseName,
path: query.file.path,
meta: query.file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [
options.parser === "zod" && /* @__PURE__ */ jsx(File.Import, {
name: [zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean),
root: query.file.path,
path: zod.file.path
}),
options.client.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: "fetch",
path: options.client.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
path: options.client.importPath,
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
path: options.client.importPath,
isTypeOnly: true
})
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["fetch"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
})
] }),
shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: [client.name],
root: query.file.path,
path: client.file.path
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["buildFormData"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/config.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
type.schemas.request?.name,
type.schemas.response.name,
type.schemas.pathParams?.name,
type.schemas.queryParams?.name,
type.schemas.headerParams?.name,
...type.schemas.statusCodes?.map((item) => item.name) || []
].filter(Boolean),
root: query.file.path,
path: type.file.path,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(QueryKey, {
name: queryKey.name,
typeName: queryKey.typeName,
operation,
paramsCasing: options.paramsCasing,
pathParamsType: options.pathParamsType,
typeSchemas: type.schemas,
transformer: options.queryKey
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(Client, {
name: client.name,
baseURL: options.client.baseURL,
operation,
typeSchemas: type.schemas,
zodSchemas: zod.schemas,
dataReturnType: options.client.dataReturnType || "data",
paramsCasing: options.client?.paramsCasing || options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
parser: options.parser
}),
options.customOptions && /* @__PURE__ */ jsx(File.Import, {
name: [options.customOptions.name],
path: options.customOptions.importPath
}),
infiniteOptions && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["InfiniteData"],
isTypeOnly: true,
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["infiniteQueryOptions"],
path: importPath
}),
/* @__PURE__ */ jsx(InfiniteQueryOptions, {
name: queryOptions.name,
clientName: client.name,
queryKeyName: queryKey.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
dataReturnType: options.client.dataReturnType || "data",
cursorParam: infiniteOptions.cursorParam,
nextParam: infiniteOptions.nextParam,
previousParam: infiniteOptions.previousParam,
initialPageParam: infiniteOptions.initialPageParam,
queryParam: infiniteOptions.queryParam
})
] }),
infiniteOptions && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["useInfiniteQuery"],
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"QueryKey",
"QueryClient",
"InfiniteQueryObserverOptions",
"UseInfiniteQueryResult"
],
path: importPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(InfiniteQuery, {
name: query.name,
queryOptionsName: queryOptions.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
operation,
dataReturnType: options.client.dataReturnType || "data",
queryKeyName: queryKey.name,
queryKeyTypeName: queryKey.typeName,
initialPageParam: infiniteOptions.initialPageParam,
queryParam: infiniteOptions.queryParam,
customOptions: options.customOptions
})
] })
]
});
}
});
//#endregion
//#region src/generators/mutationGenerator.tsx
const mutationGenerator = createReactGenerator({
name: "react-query",
Operation({ config, plugin, operation, generator }) {
const { options, options: { output } } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getSchemas, getName, getFile } = useOperationManager(generator);
const isQuery = !!options.query && options.query?.methods.some((method) => operation.method === method);
const isMutation = options.mutation !== false && !isQuery && difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
const importPath = options.mutation ? options.mutation.importPath : "@tanstack/react-query";
const mutation = {
name: getName(operation, {
type: "function",
prefix: "use"
}),
typeName: getName(operation, { type: "type" }),
file: getFile(operation, { prefix: "use" })
};
const type = {
file: getFile(operation, { pluginKey: [pluginTsName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginTsName],
type: "type"
})
};
const zod = {
file: getFile(operation, { pluginKey: [pluginZodName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginZodName],
type: "function"
})
};
const shouldUseClientPlugin = !!pluginManager.getPluginByKey([pluginClientName]) && options.client.clientType !== "class";
const client = {
name: shouldUseClientPlugin ? getName(operation, {
type: "function",
pluginKey: [pluginClientName]
}) : getName(operation, { type: "function" }),
file: getFile(operation, { pluginKey: [pluginClientName] })
};
const mutationOptions = { name: getName(operation, {
type: "function",
suffix: "MutationOptions"
}) };
const mutationKey = {
name: getName(operation, {
type: "const",
suffix: "MutationKey"
}),
typeName: getName(operation, {
type: "type",
suffix: "MutationKey"
})
};
if (!isMutation) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: mutation.file.baseName,
path: mutation.file.path,
meta: mutation.file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [
options.parser === "zod" && /* @__PURE__ */ jsx(File.Import, {
name: [zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean),
root: mutation.file.path,
path: zod.file.path
}),
options.client.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: "fetch",
path: options.client.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
path: options.client.importPath,
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
path: options.client.importPath,
isTypeOnly: true
})
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["fetch"],
root: mutation.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
root: mutation.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
root: mutation.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
})
] }),
shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: [client.name],
root: mutation.file.path,
path: client.file.path
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["buildFormData"],
root: mutation.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/config.ts")
}),
options.customOptions && /* @__PURE__ */ jsx(File.Import, {
name: [options.customOptions.name],
path: options.customOptions.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
type.schemas.request?.name,
type.schemas.response.name,
type.schemas.pathParams?.name,
type.schemas.queryParams?.name,
type.schemas.headerParams?.name,
...type.schemas.statusCodes?.map((item) => item.name) || []
].filter(Boolean),
root: mutation.file.path,
path: type.file.path,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(MutationKey, {
name: mutationKey.name,
typeName: mutationKey.typeName,
operation,
pathParamsType: options.pathParamsType,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
transformer: options.mutationKey
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(Client, {
name: client.name,
baseURL: options.client.baseURL,
operation,
typeSchemas: type.schemas,
zodSchemas: zod.schemas,
dataReturnType: options.client.dataReturnType || "data",
paramsCasing: options.client?.paramsCasing || options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
parser: options.parser
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["mutationOptions"],
path: importPath
}),
/* @__PURE__ */ jsx(MutationOptions, {
name: mutationOptions.name,
clientName: client.name,
mutationKeyName: mutationKey.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
dataReturnType: options.client.dataReturnType || "data"
}),
options.mutation && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["useMutation"],
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"UseMutationOptions",
"UseMutationResult",
"QueryClient"
],
path: importPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(Mutation, {
name: mutation.name,
mutationOptionsName: mutationOptions.name,
typeName: mutation.typeName,
typeSchemas: type.schemas,
operation,
dataReturnType: options.client.dataReturnType || "data",
paramsCasing: options.paramsCasing,
pathParamsType: options.pathParamsType,
mutationKeyName: mutationKey.name,
customOptions: options.customOptions
})
] })
]
});
}
});
//#endregion
//#region src/generators/queryGenerator.tsx
const queryGenerator = createReactGenerator({
name: "react-query",
Operation({ config, plugin, operation, generator }) {
const { options, options: { output } } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getSchemas, getName, getFile } = useOperationManager(generator);
const isQuery = typeof options.query === "boolean" ? true : options.query?.methods.some((method) => operation.method === method);
const isMutation = difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
const importPath = options.query ? options.query.importPath : "@tanstack/react-query";
const query = {
name: getName(operation, {
type: "function",
prefix: "use"
}),
typeName: getName(operation, { type: "type" }),
file: getFile(operation, { prefix: "use" })
};
const shouldUseClientPlugin = !!pluginManager.getPluginByKey([pluginClientName]) && options.client.clientType !== "class";
const client = {
name: shouldUseClientPlugin ? getName(operation, {
type: "function",
pluginKey: [pluginClientName]
}) : getName(operation, { type: "function" }),
file: getFile(operation, { pluginKey: [pluginClientName] })
};
const queryOptions = { name: getName(operation, {
type: "function",
suffix: "QueryOptions"
}) };
const queryKey = {
name: getName(operation, {
type: "const",
suffix: "QueryKey"
}),
typeName: getName(operation, {
type: "type",
suffix: "QueryKey"
})
};
const type = {
file: getFile(operation, { pluginKey: [pluginTsName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginTsName],
type: "type"
})
};
const zod = {
file: getFile(operation, { pluginKey: [pluginZodName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginZodName],
type: "function"
})
};
if (!isQuery || isMutation) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: query.file.baseName,
path: query.file.path,
meta: query.file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [
options.parser === "zod" && /* @__PURE__ */ jsx(File.Import, {
name: [zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean),
root: query.file.path,
path: zod.file.path
}),
options.client.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: "fetch",
path: options.client.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
path: options.client.importPath,
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
path: options.client.importPath,
isTypeOnly: true
})
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["fetch"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
})
] }),
shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: [client.name],
root: query.file.path,
path: client.file.path
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["buildFormData"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/config.ts")
}),
options.customOptions && /* @__PURE__ */ jsx(File.Import, {
name: [options.customOptions.name],
path: options.customOptions.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
type.schemas.request?.name,
type.schemas.response.name,
type.schemas.pathParams?.name,
type.schemas.queryParams?.name,
type.schemas.headerParams?.name,
...type.schemas.statusCodes?.map((item) => item.name) || []
].filter(Boolean),
root: query.file.path,
path: type.file.path,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(QueryKey, {
name: queryKey.name,
typeName: queryKey.typeName,
operation,
pathParamsType: options.pathParamsType,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
transformer: options.queryKey
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(Client, {
name: client.name,
baseURL: options.client.baseURL,
operation,
typeSchemas: type.schemas,
zodSchemas: zod.schemas,
dataReturnType: options.client.dataReturnType || "data",
paramsType: options.paramsType,
paramsCasing: options.client?.paramsCasing || options.paramsCasing,
pathParamsType: options.pathParamsType,
parser: options.parser
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["queryOptions"],
path: importPath
}),
/* @__PURE__ */ jsx(QueryOptions, {
name: queryOptions.name,
clientName: client.name,
queryKeyName: queryKey.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
dataReturnType: options.client.dataReturnType || "data"
}),
options.query && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["useQuery"],
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"QueryKey",
"QueryClient",
"QueryObserverOptions",
"UseQueryResult",
"QueryClient"
],
path: importPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(Query, {
name: query.name,
queryOptionsName: queryOptions.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
operation,
dataReturnType: options.client.dataReturnType || "data",
queryKeyName: queryKey.name,
queryKeyTypeName: queryKey.typeName,
customOptions: options.customOptions
})
] })
]
});
}
});
//#endregion
//#region src/generators/suspenseInfiniteQueryGenerator.tsx
const suspenseInfiniteQueryGenerator = createReactGenerator({
name: "react-suspense-infinite-query",
Operation({ config, operation, generator, plugin }) {
const { options, options: { output } } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getSchemas, getName, getFile } = useOperationManager(generator);
const isQuery = typeof options.query === "boolean" ? true : options.query?.methods.some((method) => operation.method === method);
const isMutation = difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
const isSuspense = !!options.suspense;
const infiniteOptions = options.infinite && typeof options.infinite === "object" ? options.infinite : void 0;
const importPath = options.query ? options.query.importPath : "@tanstack/react-query";
const query = {
name: getName(operation, {
type: "function",
prefix: "use",
suffix: "suspenseInfinite"
}),
typeName: getName(operation, { type: "type" }),
file: getFile(operation, {
prefix: "use",
suffix: "suspenseInfinite"
})
};
const shouldUseClientPlugin = !!pluginManager.getPluginByKey([pluginClientName]) && options.client.clientType !== "class";
const client = {
name: shouldUseClientPlugin ? getName(operation, {
type: "function",
pluginKey: [pluginClientName]
}) : getName(operation, {
type: "function",
suffix: "suspenseInfinite"
}),
file: getFile(operation, { pluginKey: [pluginClientName] })
};
const queryOptions = { name: getName(operation, {
type: "function",
suffix: "SuspenseInfiniteQueryOptions"
}) };
const queryKey = {
name: getName(operation, {
type: "const",
suffix: "SuspenseInfiniteQueryKey"
}),
typeName: getName(operation, {
type: "type",
suffix: "SuspenseInfiniteQueryKey"
})
};
const type = {
file: getFile(operation, { pluginKey: [pluginTsName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginTsName],
type: "type"
})
};
const zod = {
file: getFile(operation, { pluginKey: [pluginZodName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginZodName],
type: "function"
})
};
if (!isQuery || isMutation || !isSuspense || !infiniteOptions) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: query.file.baseName,
path: query.file.path,
meta: query.file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [
options.parser === "zod" && /* @__PURE__ */ jsx(File.Import, {
name: [zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean),
root: query.file.path,
path: zod.file.path
}),
options.client.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: "fetch",
path: options.client.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
path: options.client.importPath,
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
path: options.client.importPath,
isTypeOnly: true
})
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["fetch"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
})
] }),
shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: [client.name],
root: query.file.path,
path: client.file.path
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["buildFormData"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/config.ts")
}),
options.customOptions && /* @__PURE__ */ jsx(File.Import, {
name: [options.customOptions.name],
path: options.customOptions.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
type.schemas.request?.name,
type.schemas.response.name,
type.schemas.pathParams?.name,
type.schemas.queryParams?.name,
type.schemas.headerParams?.name,
...type.schemas.statusCodes?.map((item) => item.name) || []
].filter(Boolean),
root: query.file.path,
path: type.file.path,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(QueryKey, {
name: queryKey.name,
typeName: queryKey.typeName,
operation,
paramsCasing: options.paramsCasing,
pathParamsType: options.pathParamsType,
typeSchemas: type.schemas,
transformer: options.queryKey
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(Client, {
name: client.name,
baseURL: options.client.baseURL,
operation,
typeSchemas: type.schemas,
zodSchemas: zod.schemas,
dataReturnType: options.client.dataReturnType || "data",
paramsCasing: options.client?.paramsCasing || options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
parser: options.parser
}),
infiniteOptions && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["InfiniteData"],
isTypeOnly: true,
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["infiniteQueryOptions"],
path: importPath
}),
/* @__PURE__ */ jsx(SuspenseInfiniteQueryOptions, {
name: queryOptions.name,
clientName: client.name,
queryKeyName: queryKey.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
dataReturnType: options.client.dataReturnType || "data",
cursorParam: infiniteOptions.cursorParam,
nextParam: infiniteOptions.nextParam,
previousParam: infiniteOptions.previousParam,
initialPageParam: infiniteOptions.initialPageParam,
queryParam: infiniteOptions.queryParam
})
] }),
infiniteOptions && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["useSuspenseInfiniteQuery"],
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"QueryKey",
"QueryClient",
"UseSuspenseInfiniteQueryOptions",
"UseSuspenseInfiniteQueryResult"
],
path: importPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(SuspenseInfiniteQuery, {
name: query.name,
queryOptionsName: queryOptions.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
operation,
dataReturnType: options.client.dataReturnType || "data",
queryKeyName: queryKey.name,
queryKeyTypeName: queryKey.typeName,
customOptions: options.customOptions,
initialPageParam: infiniteOptions.initialPageParam,
queryParam: infiniteOptions.queryParam
})
] })
]
});
}
});
//#endregion
//#region src/generators/suspenseQueryGenerator.tsx
const suspenseQueryGenerator = createReactGenerator({
name: "react-suspense-query",
Operation({ config, operation, generator, plugin }) {
const { options, options: { output } } = plugin;
const pluginManager = usePluginManager();
const oas = useOas();
const { getSchemas, getName, getFile } = useOperationManager(generator);
const isQuery = typeof options.query === "boolean" ? true : options.query?.methods.some((method) => operation.method === method);
const isMutation = difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
const isSuspense = !!options.suspense;
const importPath = options.query ? options.query.importPath : "@tanstack/react-query";
const query = {
name: getName(operation, {
type: "function",
prefix: "use",
suffix: "suspense"
}),
typeName: getName(operation, { type: "type" }),
file: getFile(operation, {
prefix: "use",
suffix: "suspense"
})
};
const shouldUseClientPlugin = !!pluginManager.getPluginByKey([pluginClientName]) && options.client.clientType !== "class";
const client = {
name: shouldUseClientPlugin ? getName(operation, {
type: "function",
pluginKey: [pluginClientName]
}) : getName(operation, {
type: "function",
suffix: "suspense"
}),
file: getFile(operation, { pluginKey: [pluginClientName] })
};
const queryOptions = { name: getName(operation, {
type: "function",
suffix: "SuspenseQueryOptions"
}) };
const queryKey = {
name: getName(operation, {
type: "const",
suffix: "SuspenseQueryKey"
}),
typeName: getName(operation, {
type: "type",
suffix: "SuspenseQueryKey"
})
};
const type = {
file: getFile(operation, { pluginKey: [pluginTsName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginTsName],
type: "type"
})
};
const zod = {
file: getFile(operation, { pluginKey: [pluginZodName] }),
schemas: getSchemas(operation, {
pluginKey: [pluginZodName],
type: "function"
})
};
if (!isQuery || isMutation || !isSuspense) return null;
return /* @__PURE__ */ jsxs(File, {
baseName: query.file.baseName,
path: query.file.path,
meta: query.file.meta,
banner: getBanner({
oas,
output,
config: pluginManager.config
}),
footer: getFooter({
oas,
output
}),
children: [
options.parser === "zod" && /* @__PURE__ */ jsx(File.Import, {
name: [zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean),
root: query.file.path,
path: zod.file.path
}),
options.client.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: "fetch",
path: options.client.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
path: options.client.importPath,
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
path: options.client.importPath,
isTypeOnly: true
})
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["fetch"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts")
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"Client",
"RequestConfig",
"ResponseErrorConfig"
],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
}),
options.client.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
name: ["ResponseConfig"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/fetch.ts"),
isTypeOnly: true
})
] }),
shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: [client.name],
root: query.file.path,
path: client.file.path
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
name: ["buildFormData"],
root: query.file.path,
path: path.resolve(config.root, config.output.path, ".kubb/config.ts")
}),
options.customOptions && /* @__PURE__ */ jsx(File.Import, {
name: [options.customOptions.name],
path: options.customOptions.importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
type.schemas.request?.name,
type.schemas.response.name,
type.schemas.pathParams?.name,
type.schemas.queryParams?.name,
type.schemas.headerParams?.name,
...type.schemas.statusCodes?.map((item) => item.name) || []
].filter(Boolean),
root: query.file.path,
path: type.file.path,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(QueryKey, {
name: queryKey.name,
typeName: queryKey.typeName,
operation,
paramsCasing: options.paramsCasing,
pathParamsType: options.pathParamsType,
typeSchemas: type.schemas,
transformer: options.queryKey
}),
!shouldUseClientPlugin && /* @__PURE__ */ jsx(Client, {
name: client.name,
baseURL: options.client.baseURL,
operation,
typeSchemas: type.schemas,
zodSchemas: zod.schemas,
dataReturnType: options.client.dataReturnType || "data",
paramsCasing: options.client?.paramsCasing || options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
parser: options.parser
}),
/* @__PURE__ */ jsx(File.Import, {
name: ["queryOptions"],
path: importPath
}),
/* @__PURE__ */ jsx(QueryOptions, {
name: queryOptions.name,
clientName: client.name,
queryKeyName: queryKey.name,
typeSchemas: type.schemas,
paramsCasing: options.paramsCasing,
paramsType: options.paramsType,
pathParamsType: options.pathParamsType,
dataReturnType: options.client.dataReturnType
}),
options.suspense && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(File.Import, {
name: ["useSuspenseQuery"],
path: importPath
}),
/* @__PURE__ */ jsx(File.Import, {
name: [
"QueryKey",
"QueryClient",
"UseSuspenseQueryOptions",
"UseSuspenseQueryResult"
],
path: importPath,
isTypeOnly: true
}),
/* @__PURE__ */ jsx(SuspenseQuery, {
name: query.name,
queryOptionsName: queryOptions.name,
typeSchemas: type.schemas,
paramsType: options.paramsType,
paramsCasing: options.paramsCasing,
pathParamsType: options.pathParamsType,
operation,
dataReturnType: options.client.dataReturnType || "data",
queryKeyName: queryKey.name,
queryKeyTypeName: queryKey.typeName,
customOptions: options.customOptions
})
] })
]
});
}
});
//#endregion
export { infiniteQueryGenerator as a, mutationGenerator as i, suspenseInfiniteQueryGenerator as n, hookOptionsGenerator as o, queryGenerator as r, customHookOptionsFileGenerator as s, suspenseQueryGenerator as t };
//# sourceMappingURL=generators-CpiBv5eE.js.map