@7nohe/openapi-react-query-codegen 2.2.0 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common.mjs +1 -74
- package/dist/createSource.mjs +13 -107
- package/dist/generate.mjs +1 -1
- package/dist/parseOperations.mjs +122 -0
- package/dist/tsmorph/buildCommon.mjs +119 -0
- package/dist/tsmorph/buildKeys.mjs +110 -0
- package/dist/tsmorph/buildMutationHooks.mjs +51 -0
- package/dist/tsmorph/buildQueryHooks.mjs +237 -0
- package/dist/tsmorph/generateFiles.mjs +205 -0
- package/dist/tsmorph/index.mjs +5 -0
- package/dist/tsmorph/projectFactory.mjs +121 -0
- package/dist/types.mjs +1 -0
- package/package.json +1 -1
- package/dist/createExports.mjs +0 -121
- package/dist/createImports.mjs +0 -54
- package/dist/createPrefetchOrEnsure.mjs +0 -56
- package/dist/createUseMutation.mjs +0 -97
- package/dist/createUseQuery.mjs +0 -256
package/dist/createExports.mjs
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { capitalizeFirstLetter } from "./common.mjs";
|
|
3
|
-
import { modelsFileName } from "./constants.mjs";
|
|
4
|
-
import { createPrefetchOrEnsure } from "./createPrefetchOrEnsure.mjs";
|
|
5
|
-
import { createUseMutation } from "./createUseMutation.mjs";
|
|
6
|
-
import { createUseQuery } from "./createUseQuery.mjs";
|
|
7
|
-
export const createExports = ({ service, client, project, pageParam, nextPageParam, initialPageParam, }) => {
|
|
8
|
-
const { methods } = service;
|
|
9
|
-
const methodDataNames = methods.reduce((acc, data) => {
|
|
10
|
-
const methodName = data.method.getName();
|
|
11
|
-
acc[`${capitalizeFirstLetter(methodName)}Data`] = methodName;
|
|
12
|
-
return acc;
|
|
13
|
-
}, {});
|
|
14
|
-
const modelsFile = project
|
|
15
|
-
.getSourceFiles?.()
|
|
16
|
-
.find((sourceFile) => sourceFile.getFilePath().includes(modelsFileName));
|
|
17
|
-
const modelDeclarations = modelsFile?.getExportedDeclarations();
|
|
18
|
-
const entries = modelDeclarations?.entries();
|
|
19
|
-
const modelNames = [];
|
|
20
|
-
const paginatableMethods = [];
|
|
21
|
-
for (const [key, value] of entries ?? []) {
|
|
22
|
-
modelNames.push(key);
|
|
23
|
-
const node = value[0].compilerNode;
|
|
24
|
-
if (ts.isTypeAliasDeclaration(node) && methodDataNames[key] !== undefined) {
|
|
25
|
-
// get the type alias declaration
|
|
26
|
-
const typeAliasDeclaration = node.type;
|
|
27
|
-
if (ts.isTypeLiteralNode(typeAliasDeclaration)) {
|
|
28
|
-
const query = typeAliasDeclaration.members.find((m) => ts.isPropertySignature(m) && m.name?.getText() === "query");
|
|
29
|
-
if (query) {
|
|
30
|
-
const queryType = query.type;
|
|
31
|
-
const members = queryType && ts.isTypeLiteralNode(queryType)
|
|
32
|
-
? queryType.members
|
|
33
|
-
: undefined;
|
|
34
|
-
if (members?.map((m) => m.name?.getText()).includes(pageParam)) {
|
|
35
|
-
paginatableMethods.push(methodDataNames[key]);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const allGet = methods.filter((m) => m.httpMethodName.toUpperCase().includes("GET"));
|
|
42
|
-
const allPost = methods.filter((m) => m.httpMethodName.toUpperCase().includes("POST"));
|
|
43
|
-
const allPut = methods.filter((m) => m.httpMethodName.toUpperCase().includes("PUT"));
|
|
44
|
-
const allPatch = methods.filter((m) => m.httpMethodName.toUpperCase().includes("PATCH"));
|
|
45
|
-
const allDelete = methods.filter((m) => m.httpMethodName.toUpperCase().includes("DELETE"));
|
|
46
|
-
const allGetQueries = allGet.map((m) => createUseQuery({
|
|
47
|
-
functionDescription: m,
|
|
48
|
-
client,
|
|
49
|
-
pageParam,
|
|
50
|
-
nextPageParam,
|
|
51
|
-
initialPageParam,
|
|
52
|
-
paginatableMethods,
|
|
53
|
-
modelNames,
|
|
54
|
-
}));
|
|
55
|
-
const allPrefetchQueries = allGet.map((m) => createPrefetchOrEnsure({ ...m, functionType: "prefetch", modelNames }));
|
|
56
|
-
const allEnsureQueries = allGet.map((m) => createPrefetchOrEnsure({ ...m, functionType: "ensure", modelNames }));
|
|
57
|
-
const allPostMutations = allPost.map((m) => createUseMutation({ functionDescription: m, modelNames, client }));
|
|
58
|
-
const allPutMutations = allPut.map((m) => createUseMutation({ functionDescription: m, modelNames, client }));
|
|
59
|
-
const allPatchMutations = allPatch.map((m) => createUseMutation({ functionDescription: m, modelNames, client }));
|
|
60
|
-
const allDeleteMutations = allDelete.map((m) => createUseMutation({ functionDescription: m, modelNames, client }));
|
|
61
|
-
const allQueries = [...allGetQueries];
|
|
62
|
-
const allMutations = [
|
|
63
|
-
...allPostMutations,
|
|
64
|
-
...allPutMutations,
|
|
65
|
-
...allPatchMutations,
|
|
66
|
-
...allDeleteMutations,
|
|
67
|
-
];
|
|
68
|
-
const commonInQueries = allQueries.flatMap(({ apiResponse, returnType, key, queryKeyFn }) => [
|
|
69
|
-
apiResponse,
|
|
70
|
-
returnType,
|
|
71
|
-
key,
|
|
72
|
-
queryKeyFn,
|
|
73
|
-
]);
|
|
74
|
-
const commonInMutations = allMutations.flatMap(({ mutationResult, key, mutationKeyFn }) => [
|
|
75
|
-
mutationResult,
|
|
76
|
-
key,
|
|
77
|
-
mutationKeyFn,
|
|
78
|
-
]);
|
|
79
|
-
const allCommon = [...commonInQueries, ...commonInMutations];
|
|
80
|
-
const mainQueries = allQueries.flatMap(({ queryHook }) => [queryHook]);
|
|
81
|
-
const mainMutations = allMutations.flatMap(({ mutationHook }) => [
|
|
82
|
-
mutationHook,
|
|
83
|
-
]);
|
|
84
|
-
const mainExports = [...mainQueries, ...mainMutations];
|
|
85
|
-
const infiniteQueriesExports = allQueries
|
|
86
|
-
.flatMap(({ infiniteQueryHook }) => [infiniteQueryHook])
|
|
87
|
-
.filter((x) => x != null);
|
|
88
|
-
const suspenseQueries = allQueries.flatMap(({ suspenseQueryHook }) => [
|
|
89
|
-
suspenseQueryHook,
|
|
90
|
-
]);
|
|
91
|
-
const suspenseExports = [...suspenseQueries];
|
|
92
|
-
const allPrefetches = allPrefetchQueries.flatMap(({ hook }) => [hook]);
|
|
93
|
-
const allEnsures = allEnsureQueries.flatMap(({ hook }) => [hook]);
|
|
94
|
-
const allPrefetchExports = [...allPrefetches];
|
|
95
|
-
return {
|
|
96
|
-
/**
|
|
97
|
-
* Common types and variables between queries (regular and suspense) and mutations
|
|
98
|
-
*/
|
|
99
|
-
allCommon,
|
|
100
|
-
/**
|
|
101
|
-
* Main exports are the hooks that are used in the components
|
|
102
|
-
*/
|
|
103
|
-
mainExports,
|
|
104
|
-
/**
|
|
105
|
-
* Infinite queries exports are the hooks that are used in the infinite scroll components
|
|
106
|
-
*/
|
|
107
|
-
infiniteQueriesExports,
|
|
108
|
-
/**
|
|
109
|
-
* Suspense exports are the hooks that are used in the suspense components
|
|
110
|
-
*/
|
|
111
|
-
suspenseExports,
|
|
112
|
-
/**
|
|
113
|
-
* Prefetch exports are the hooks that are used in the prefetch components
|
|
114
|
-
*/
|
|
115
|
-
allPrefetchExports,
|
|
116
|
-
/**
|
|
117
|
-
* Ensure exports are the hooks that are used in the loader components
|
|
118
|
-
*/
|
|
119
|
-
allEnsures,
|
|
120
|
-
};
|
|
121
|
-
};
|
package/dist/createImports.mjs
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { posix } from "node:path";
|
|
2
|
-
import ts from "typescript";
|
|
3
|
-
import { modelsFileName, serviceFileName } from "./constants.mjs";
|
|
4
|
-
const { join } = posix;
|
|
5
|
-
export const createImports = ({ project, client, }) => {
|
|
6
|
-
const modelsFile = project
|
|
7
|
-
.getSourceFiles()
|
|
8
|
-
.find((sourceFile) => sourceFile.getFilePath().includes(modelsFileName));
|
|
9
|
-
const serviceFile = project.getSourceFileOrThrow(`${serviceFileName}.ts`);
|
|
10
|
-
if (!modelsFile) {
|
|
11
|
-
console.warn(`
|
|
12
|
-
⚠️ WARNING: No models file found.
|
|
13
|
-
This may be an error if \`.components.schemas\` or \`.components.parameters\` is defined in your OpenAPI input.`);
|
|
14
|
-
}
|
|
15
|
-
const modelNames = modelsFile
|
|
16
|
-
? Array.from(modelsFile.getExportedDeclarations().keys())
|
|
17
|
-
: [];
|
|
18
|
-
const serviceExports = Array.from(serviceFile.getExportedDeclarations().keys());
|
|
19
|
-
// Filter out type-only exports (e.g. Options) to avoid duplicate imports,
|
|
20
|
-
// since Options is already imported separately from the client module.
|
|
21
|
-
const serviceNames = serviceExports.filter((name) => name !== "Options");
|
|
22
|
-
const imports = [
|
|
23
|
-
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(true, undefined, ts.factory.createNamedImports([
|
|
24
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("Options")),
|
|
25
|
-
])), ts.factory.createStringLiteral(join("../requests", serviceFileName)), undefined),
|
|
26
|
-
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
27
|
-
ts.factory.createImportSpecifier(true, undefined, ts.factory.createIdentifier("QueryClient")),
|
|
28
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useQuery")),
|
|
29
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useSuspenseQuery")),
|
|
30
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useMutation")),
|
|
31
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("UseQueryResult")),
|
|
32
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("UseQueryOptions")),
|
|
33
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("UseMutationOptions")),
|
|
34
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("UseMutationResult")),
|
|
35
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("UseSuspenseQueryOptions")),
|
|
36
|
-
])), ts.factory.createStringLiteral("@tanstack/react-query"), undefined),
|
|
37
|
-
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
38
|
-
// import all class names from service file
|
|
39
|
-
...serviceNames.map((serviceName) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(serviceName))),
|
|
40
|
-
])), ts.factory.createStringLiteral(join("../requests", serviceFileName)), undefined),
|
|
41
|
-
];
|
|
42
|
-
if (modelsFile) {
|
|
43
|
-
// import all the models by name
|
|
44
|
-
imports.push(ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
45
|
-
...modelNames.map((modelName) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(modelName))),
|
|
46
|
-
])), ts.factory.createStringLiteral(join("../requests/", modelsFileName)), undefined));
|
|
47
|
-
}
|
|
48
|
-
if (client === "@hey-api/client-axios") {
|
|
49
|
-
imports.push(ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
50
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("AxiosError")),
|
|
51
|
-
])), ts.factory.createStringLiteral("axios")));
|
|
52
|
-
}
|
|
53
|
-
return imports;
|
|
54
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { BuildCommonTypeName, EqualsOrGreaterThanToken, getNameFromVariable, getQueryKeyFnName, getRequestParamFromMethod, getVariableArrowFunctionParameters, } from "./common.mjs";
|
|
3
|
-
import { createQueryKeyFromMethod, hookNameFromMethod, } from "./createUseQuery.mjs";
|
|
4
|
-
import { addJSDocToNode } from "./util.mjs";
|
|
5
|
-
/**
|
|
6
|
-
* Creates a prefetch/ensure function for a query
|
|
7
|
-
*/
|
|
8
|
-
function createPrefetchOrEnsureHook({ requestParams, method, functionType, }) {
|
|
9
|
-
const methodName = getNameFromVariable(method);
|
|
10
|
-
const queryName = hookNameFromMethod({ method });
|
|
11
|
-
let customHookName = `prefetch${queryName.charAt(0).toUpperCase() + queryName.slice(1)}`;
|
|
12
|
-
if (functionType === "ensure") {
|
|
13
|
-
customHookName = `ensure${queryName.charAt(0).toUpperCase() + queryName.slice(1)}Data`;
|
|
14
|
-
}
|
|
15
|
-
const queryKey = createQueryKeyFromMethod({ method });
|
|
16
|
-
// const
|
|
17
|
-
const hookExport = ts.factory.createVariableStatement(
|
|
18
|
-
// export
|
|
19
|
-
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
|
|
20
|
-
ts.factory.createVariableDeclaration(ts.factory.createIdentifier(customHookName), undefined, undefined, ts.factory.createArrowFunction(undefined, undefined, [
|
|
21
|
-
ts.factory.createParameterDeclaration(undefined, undefined, "queryClient", undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("QueryClient"))),
|
|
22
|
-
...requestParams,
|
|
23
|
-
], undefined, EqualsOrGreaterThanToken, ts.factory.createCallExpression(ts.factory.createIdentifier(`queryClient.${functionType === "prefetch" ? "prefetchQuery" : "ensureQueryData"}`), undefined, [
|
|
24
|
-
ts.factory.createObjectLiteralExpression([
|
|
25
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(queryKey)), undefined, [ts.factory.createIdentifier("clientOptions")])),
|
|
26
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, [], undefined, EqualsOrGreaterThanToken, ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(ts.factory.createIdentifier(methodName), undefined,
|
|
27
|
-
// { ...clientOptions }
|
|
28
|
-
getVariableArrowFunctionParameters(method).length
|
|
29
|
-
? [
|
|
30
|
-
ts.factory.createObjectLiteralExpression([
|
|
31
|
-
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("clientOptions")),
|
|
32
|
-
]),
|
|
33
|
-
]
|
|
34
|
-
: undefined), ts.factory.createIdentifier("then")), undefined, [
|
|
35
|
-
ts.factory.createArrowFunction(undefined, undefined, [
|
|
36
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("response"), undefined, undefined, undefined),
|
|
37
|
-
], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("response"), ts.factory.createIdentifier("data"))),
|
|
38
|
-
]))),
|
|
39
|
-
]),
|
|
40
|
-
]))),
|
|
41
|
-
], ts.NodeFlags.Const));
|
|
42
|
-
return hookExport;
|
|
43
|
-
}
|
|
44
|
-
export const createPrefetchOrEnsure = ({ method, jsDoc, functionType, modelNames, }) => {
|
|
45
|
-
const requestParam = getRequestParamFromMethod(method, undefined, modelNames);
|
|
46
|
-
const requestParams = requestParam ? [requestParam] : [];
|
|
47
|
-
const prefetchOrEnsureHook = createPrefetchOrEnsureHook({
|
|
48
|
-
requestParams,
|
|
49
|
-
method,
|
|
50
|
-
functionType,
|
|
51
|
-
});
|
|
52
|
-
const hookWithJsDoc = addJSDocToNode(prefetchOrEnsureHook, jsDoc);
|
|
53
|
-
return {
|
|
54
|
-
hook: hookWithJsDoc,
|
|
55
|
-
};
|
|
56
|
-
};
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { BuildCommonTypeName, EqualsOrGreaterThanToken, TContext, TData, TError, capitalizeFirstLetter, createQueryKeyExport, createQueryKeyFnExport, getNameFromVariable, getQueryKeyFnName, getVariableArrowFunctionParameters, queryKeyConstraint, queryKeyGenericType, } from "./common.mjs";
|
|
3
|
-
import { createQueryKeyFromMethod } from "./createUseQuery.mjs";
|
|
4
|
-
import { addJSDocToNode } from "./util.mjs";
|
|
5
|
-
/**
|
|
6
|
-
* Awaited<ReturnType<typeof myClass.myMethod>>
|
|
7
|
-
*/
|
|
8
|
-
function generateAwaitedReturnType({ methodName }) {
|
|
9
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Awaited"), [
|
|
10
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("ReturnType"), [
|
|
11
|
-
ts.factory.createTypeQueryNode(ts.factory.createIdentifier(methodName), undefined),
|
|
12
|
-
]),
|
|
13
|
-
]);
|
|
14
|
-
}
|
|
15
|
-
export const createUseMutation = ({ functionDescription: { method, jsDoc }, modelNames, client, }) => {
|
|
16
|
-
const methodName = getNameFromVariable(method);
|
|
17
|
-
const mutationKey = createQueryKeyFromMethod({ method });
|
|
18
|
-
const awaitedResponseDataType = generateAwaitedReturnType({
|
|
19
|
-
methodName,
|
|
20
|
-
});
|
|
21
|
-
const mutationResult = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${capitalizeFirstLetter(methodName)}MutationResult`), undefined, awaitedResponseDataType);
|
|
22
|
-
// `TData = Common.AddPetMutationResult`
|
|
23
|
-
const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(mutationResult.name)));
|
|
24
|
-
// @hey-api/client-axios -> `TError = AxiosError<AddPetError>`
|
|
25
|
-
// @hey-api/client-fetch -> `TError = AddPetError`
|
|
26
|
-
const errorTypeName = `${capitalizeFirstLetter(methodName)}Error`;
|
|
27
|
-
const hasErrorType = modelNames.includes(errorTypeName);
|
|
28
|
-
const responseErrorType = ts.factory.createTypeParameterDeclaration(undefined, TError, undefined, hasErrorType
|
|
29
|
-
? client === "@hey-api/client-axios"
|
|
30
|
-
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [
|
|
31
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(errorTypeName)),
|
|
32
|
-
])
|
|
33
|
-
: ts.factory.createTypeReferenceNode(errorTypeName)
|
|
34
|
-
: client === "@hey-api/client-axios"
|
|
35
|
-
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)])
|
|
36
|
-
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
37
|
-
const methodParameters = getVariableArrowFunctionParameters(method).length !== 0
|
|
38
|
-
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Options"), [
|
|
39
|
-
ts.factory.createTypeReferenceNode(modelNames.includes(`${capitalizeFirstLetter(methodName)}Data`)
|
|
40
|
-
? `${capitalizeFirstLetter(methodName)}Data`
|
|
41
|
-
: "unknown"),
|
|
42
|
-
ts.factory.createLiteralTypeNode(ts.factory.createTrue()),
|
|
43
|
-
])
|
|
44
|
-
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
|
|
45
|
-
const exportHook = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
|
|
46
|
-
ts.factory.createVariableDeclaration(ts.factory.createIdentifier(`use${capitalizeFirstLetter(methodName)}`), undefined, undefined, ts.factory.createArrowFunction(undefined, ts.factory.createNodeArray([
|
|
47
|
-
responseDataType,
|
|
48
|
-
responseErrorType,
|
|
49
|
-
ts.factory.createTypeParameterDeclaration(undefined, "TQueryKey", queryKeyConstraint, ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword))),
|
|
50
|
-
ts.factory.createTypeParameterDeclaration(undefined, TContext, undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)),
|
|
51
|
-
]), [
|
|
52
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("mutationKey"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), queryKeyGenericType),
|
|
53
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("options"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Omit"), [
|
|
54
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("UseMutationOptions"), [
|
|
55
|
-
ts.factory.createTypeReferenceNode(TData),
|
|
56
|
-
ts.factory.createTypeReferenceNode(TError),
|
|
57
|
-
methodParameters,
|
|
58
|
-
ts.factory.createTypeReferenceNode(TContext),
|
|
59
|
-
]),
|
|
60
|
-
ts.factory.createUnionTypeNode([
|
|
61
|
-
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("mutationKey")),
|
|
62
|
-
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("mutationFn")),
|
|
63
|
-
]),
|
|
64
|
-
]), undefined),
|
|
65
|
-
], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression(ts.factory.createIdentifier("useMutation"), [
|
|
66
|
-
ts.factory.createTypeReferenceNode(TData),
|
|
67
|
-
ts.factory.createTypeReferenceNode(TError),
|
|
68
|
-
methodParameters,
|
|
69
|
-
ts.factory.createTypeReferenceNode(TContext),
|
|
70
|
-
], [
|
|
71
|
-
ts.factory.createObjectLiteralExpression([
|
|
72
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("mutationKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(mutationKey)), undefined, [ts.factory.createIdentifier("mutationKey")])),
|
|
73
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("mutationFn"),
|
|
74
|
-
// (clientOptions) => addPet(clientOptions).then(response => response.data as TData) as unknown as Promise<TData>
|
|
75
|
-
ts.factory.createArrowFunction(undefined, undefined, [
|
|
76
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("clientOptions"), undefined, undefined, undefined),
|
|
77
|
-
], undefined, EqualsOrGreaterThanToken, ts.factory.createAsExpression(ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createIdentifier(methodName), undefined, getVariableArrowFunctionParameters(method).length >
|
|
78
|
-
0
|
|
79
|
-
? [ts.factory.createIdentifier("clientOptions")]
|
|
80
|
-
: undefined), ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Promise"), [ts.factory.createTypeReferenceNode(TData)])))),
|
|
81
|
-
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
|
|
82
|
-
]),
|
|
83
|
-
]))),
|
|
84
|
-
], ts.NodeFlags.Const));
|
|
85
|
-
const hookWithJsDoc = addJSDocToNode(exportHook, jsDoc);
|
|
86
|
-
const mutationKeyExport = createQueryKeyExport({
|
|
87
|
-
methodName,
|
|
88
|
-
queryKey: mutationKey,
|
|
89
|
-
});
|
|
90
|
-
const mutationKeyFn = createQueryKeyFnExport(mutationKey, method, "mutation");
|
|
91
|
-
return {
|
|
92
|
-
mutationResult,
|
|
93
|
-
key: mutationKeyExport,
|
|
94
|
-
mutationHook: hookWithJsDoc,
|
|
95
|
-
mutationKeyFn,
|
|
96
|
-
};
|
|
97
|
-
};
|
package/dist/createUseQuery.mjs
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { BuildCommonTypeName, EqualsOrGreaterThanToken, TData, TError, capitalizeFirstLetter, createQueryKeyExport, createQueryKeyFnExport, getNameFromVariable, getQueryKeyFnName, getRequestParamFromMethod, getVariableArrowFunctionParameters, queryKeyConstraint, queryKeyGenericType, } from "./common.mjs";
|
|
3
|
-
import { addJSDocToNode } from "./util.mjs";
|
|
4
|
-
const createApiResponseType = ({ methodName, client, modelNames, }) => {
|
|
5
|
-
/** Awaited<ReturnType<typeof myClass.myMethod>> */
|
|
6
|
-
const awaitedResponseDataType = ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Awaited"), [
|
|
7
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("ReturnType"), [
|
|
8
|
-
ts.factory.createTypeQueryNode(ts.factory.createIdentifier(methodName), undefined),
|
|
9
|
-
]),
|
|
10
|
-
]), ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("data")));
|
|
11
|
-
/** DefaultResponseDataType
|
|
12
|
-
* export type MyClassMethodDefaultResponse = Awaited<ReturnType<typeof myClass.myMethod>>
|
|
13
|
-
*/
|
|
14
|
-
const apiResponse = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${capitalizeFirstLetter(methodName)}DefaultResponse`), undefined, awaitedResponseDataType);
|
|
15
|
-
const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData.text, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(apiResponse.name)));
|
|
16
|
-
// Response data type for suspense - wrap with NonNullable to exclude undefined
|
|
17
|
-
const suspenseResponseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData.text, undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("NonNullable"), [
|
|
18
|
-
ts.factory.createTypeReferenceNode(BuildCommonTypeName(apiResponse.name)),
|
|
19
|
-
]));
|
|
20
|
-
const errorTypeName = `${capitalizeFirstLetter(methodName)}Error`;
|
|
21
|
-
const hasErrorType = modelNames.includes(errorTypeName);
|
|
22
|
-
const responseErrorType = ts.factory.createTypeParameterDeclaration(undefined, TError.text, undefined, hasErrorType
|
|
23
|
-
? client === "@hey-api/client-axios"
|
|
24
|
-
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [
|
|
25
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(errorTypeName)),
|
|
26
|
-
])
|
|
27
|
-
: ts.factory.createTypeReferenceNode(errorTypeName)
|
|
28
|
-
: client === "@hey-api/client-axios"
|
|
29
|
-
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)])
|
|
30
|
-
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
31
|
-
return {
|
|
32
|
-
/**
|
|
33
|
-
* DefaultResponseDataType
|
|
34
|
-
*
|
|
35
|
-
* export type MyClassMethodDefaultResponse = Awaited<ReturnType<typeof myClass.myMethod>>
|
|
36
|
-
*/
|
|
37
|
-
apiResponse,
|
|
38
|
-
/**
|
|
39
|
-
* This will be the name of the type of the response type of the method
|
|
40
|
-
*
|
|
41
|
-
* MyClassMethodDefaultResponse
|
|
42
|
-
*/
|
|
43
|
-
responseDataType,
|
|
44
|
-
/**
|
|
45
|
-
* ResponseDataType for suspense - wrap with NonNullable to exclude undefined
|
|
46
|
-
*
|
|
47
|
-
* NonNullable<MyClassMethodDefaultResponse>
|
|
48
|
-
*/
|
|
49
|
-
suspenseResponseDataType,
|
|
50
|
-
/**
|
|
51
|
-
* ErrorDataType
|
|
52
|
-
*
|
|
53
|
-
* MyClassMethodError
|
|
54
|
-
*/
|
|
55
|
-
responseErrorType,
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Return Type
|
|
60
|
-
*
|
|
61
|
-
* export const classNameMethodNameQueryResult<TData = MyClassMethodDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>;
|
|
62
|
-
*/
|
|
63
|
-
function createReturnTypeExport({ methodName, defaultApiResponse, }) {
|
|
64
|
-
return ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${capitalizeFirstLetter(methodName)}QueryResult`), [
|
|
65
|
-
ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(defaultApiResponse.name)),
|
|
66
|
-
ts.factory.createTypeParameterDeclaration(undefined, TError, undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)),
|
|
67
|
-
], ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("UseQueryResult"), [
|
|
68
|
-
ts.factory.createTypeReferenceNode(TData),
|
|
69
|
-
ts.factory.createTypeReferenceNode(TError),
|
|
70
|
-
]));
|
|
71
|
-
}
|
|
72
|
-
export function hookNameFromMethod({ method, }) {
|
|
73
|
-
const methodName = getNameFromVariable(method);
|
|
74
|
-
return `use${capitalizeFirstLetter(methodName)}`;
|
|
75
|
-
}
|
|
76
|
-
export function createQueryKeyFromMethod({ method, }) {
|
|
77
|
-
const customHookName = hookNameFromMethod({ method });
|
|
78
|
-
const queryKey = `${customHookName}Key`;
|
|
79
|
-
return queryKey;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Creates a custom hook for a query
|
|
83
|
-
* @param queryString The type of query to use from react-query
|
|
84
|
-
* @param suffix The suffix to append to the hook name
|
|
85
|
-
*/
|
|
86
|
-
function createQueryHook({ queryString, suffix, responseDataType, responseErrorType, requestParams, method, pageParam, nextPageParam, initialPageParam, }) {
|
|
87
|
-
const methodName = getNameFromVariable(method);
|
|
88
|
-
const customHookName = hookNameFromMethod({ method });
|
|
89
|
-
const queryKey = createQueryKeyFromMethod({ method });
|
|
90
|
-
if (queryString === "useInfiniteQuery" &&
|
|
91
|
-
(pageParam === undefined || nextPageParam === undefined)) {
|
|
92
|
-
throw new Error("pageParam and nextPageParam are required for infinite queries");
|
|
93
|
-
}
|
|
94
|
-
const isInfiniteQuery = queryString === "useInfiniteQuery";
|
|
95
|
-
const isSuspenseQuery = queryString === "useSuspenseQuery";
|
|
96
|
-
// ts.TypeParameterDeclaration.default is ts.TypeNode | undefined.
|
|
97
|
-
// We know it's a TypeReferenceNode with an Identifier typeName because we created it
|
|
98
|
-
// via ts.factory in createApiResponseType, but TypeScript cannot infer the specific subtype.
|
|
99
|
-
const responseDataTypeRef = responseDataType.default;
|
|
100
|
-
const responseDataTypeIdentifier = responseDataTypeRef.typeName;
|
|
101
|
-
const hookExport = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
|
|
102
|
-
ts.factory.createVariableDeclaration(ts.factory.createIdentifier(`${customHookName}${suffix}`), undefined, undefined, ts.factory.createArrowFunction(undefined, ts.factory.createNodeArray([
|
|
103
|
-
isInfiniteQuery
|
|
104
|
-
? ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("InfiniteData"), [
|
|
105
|
-
ts.factory.createTypeReferenceNode(responseDataTypeIdentifier),
|
|
106
|
-
]))
|
|
107
|
-
: responseDataType,
|
|
108
|
-
responseErrorType,
|
|
109
|
-
ts.factory.createTypeParameterDeclaration(undefined, "TQueryKey", queryKeyConstraint, ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword))),
|
|
110
|
-
]), [
|
|
111
|
-
...requestParams,
|
|
112
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("queryKey"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), queryKeyGenericType),
|
|
113
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("options"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Omit"), [
|
|
114
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(isInfiniteQuery
|
|
115
|
-
? "UseInfiniteQueryOptions"
|
|
116
|
-
: isSuspenseQuery
|
|
117
|
-
? "UseSuspenseQueryOptions"
|
|
118
|
-
: "UseQueryOptions"), [
|
|
119
|
-
ts.factory.createTypeReferenceNode(TData),
|
|
120
|
-
ts.factory.createTypeReferenceNode(TError),
|
|
121
|
-
]),
|
|
122
|
-
ts.factory.createUnionTypeNode([
|
|
123
|
-
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("queryKey")),
|
|
124
|
-
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("queryFn")),
|
|
125
|
-
]),
|
|
126
|
-
])),
|
|
127
|
-
], undefined, EqualsOrGreaterThanToken, ts.factory.createCallExpression(ts.factory.createIdentifier(queryString), isInfiniteQuery
|
|
128
|
-
? []
|
|
129
|
-
: [
|
|
130
|
-
ts.factory.createTypeReferenceNode(TData),
|
|
131
|
-
ts.factory.createTypeReferenceNode(TError),
|
|
132
|
-
], [
|
|
133
|
-
ts.factory.createObjectLiteralExpression([
|
|
134
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(queryKey)), undefined, [
|
|
135
|
-
ts.factory.createIdentifier("clientOptions"),
|
|
136
|
-
ts.factory.createIdentifier("queryKey"),
|
|
137
|
-
])),
|
|
138
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, isInfiniteQuery
|
|
139
|
-
? [
|
|
140
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern([
|
|
141
|
-
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier("pageParam"), undefined),
|
|
142
|
-
]), undefined, undefined),
|
|
143
|
-
]
|
|
144
|
-
: [], undefined, EqualsOrGreaterThanToken, ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(ts.factory.createIdentifier(methodName), undefined, pageParam && isInfiniteQuery
|
|
145
|
-
? [
|
|
146
|
-
// { ...clientOptions, query: { ...clientOptions.query, page: pageParam as number } }
|
|
147
|
-
ts.factory.createObjectLiteralExpression([
|
|
148
|
-
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("clientOptions")),
|
|
149
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("query"), ts.factory.createObjectLiteralExpression([
|
|
150
|
-
ts.factory.createSpreadAssignment(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("clientOptions"), ts.factory.createIdentifier("query"))),
|
|
151
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier(pageParam), ts.factory.createAsExpression(ts.factory.createIdentifier("pageParam"), ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword))),
|
|
152
|
-
])),
|
|
153
|
-
]),
|
|
154
|
-
]
|
|
155
|
-
: // { ...clientOptions }
|
|
156
|
-
getVariableArrowFunctionParameters(method)
|
|
157
|
-
.length > 0
|
|
158
|
-
? [
|
|
159
|
-
ts.factory.createObjectLiteralExpression([
|
|
160
|
-
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("clientOptions")),
|
|
161
|
-
]),
|
|
162
|
-
]
|
|
163
|
-
: undefined), ts.factory.createIdentifier("then")), undefined, [
|
|
164
|
-
ts.factory.createArrowFunction(undefined, undefined, [
|
|
165
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("response"), undefined, undefined, undefined),
|
|
166
|
-
], undefined, EqualsOrGreaterThanToken, ts.factory.createAsExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("response"), ts.factory.createIdentifier("data")), ts.factory.createTypeReferenceNode(TData))),
|
|
167
|
-
]), ts.factory.createTypeReferenceNode(TData)))),
|
|
168
|
-
...createInfiniteQueryParams(pageParam, nextPageParam, initialPageParam),
|
|
169
|
-
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
|
|
170
|
-
]),
|
|
171
|
-
]))),
|
|
172
|
-
], ts.NodeFlags.Const));
|
|
173
|
-
return hookExport;
|
|
174
|
-
}
|
|
175
|
-
export const createUseQuery = ({ functionDescription: { method, jsDoc }, client, pageParam, nextPageParam, initialPageParam, paginatableMethods, modelNames, }) => {
|
|
176
|
-
const methodName = getNameFromVariable(method);
|
|
177
|
-
const queryKey = createQueryKeyFromMethod({ method });
|
|
178
|
-
const { apiResponse: defaultApiResponse, responseDataType, suspenseResponseDataType, responseErrorType, } = createApiResponseType({
|
|
179
|
-
methodName,
|
|
180
|
-
client,
|
|
181
|
-
modelNames,
|
|
182
|
-
});
|
|
183
|
-
const requestParam = getRequestParamFromMethod(method, undefined, modelNames);
|
|
184
|
-
const infiniteRequestParam = getRequestParamFromMethod(method, pageParam, modelNames);
|
|
185
|
-
const requestParams = requestParam ? [requestParam] : [];
|
|
186
|
-
const queryHook = createQueryHook({
|
|
187
|
-
queryString: "useQuery",
|
|
188
|
-
suffix: "",
|
|
189
|
-
responseDataType,
|
|
190
|
-
responseErrorType,
|
|
191
|
-
requestParams,
|
|
192
|
-
method,
|
|
193
|
-
});
|
|
194
|
-
const suspenseQueryHook = createQueryHook({
|
|
195
|
-
queryString: "useSuspenseQuery",
|
|
196
|
-
suffix: "Suspense",
|
|
197
|
-
responseDataType: suspenseResponseDataType,
|
|
198
|
-
responseErrorType,
|
|
199
|
-
requestParams,
|
|
200
|
-
method,
|
|
201
|
-
});
|
|
202
|
-
const isInfiniteQuery = paginatableMethods.includes(methodName);
|
|
203
|
-
const infiniteQueryHook = isInfiniteQuery
|
|
204
|
-
? createQueryHook({
|
|
205
|
-
queryString: "useInfiniteQuery",
|
|
206
|
-
suffix: "Infinite",
|
|
207
|
-
responseDataType,
|
|
208
|
-
responseErrorType,
|
|
209
|
-
requestParams: infiniteRequestParam ? [infiniteRequestParam] : [],
|
|
210
|
-
method,
|
|
211
|
-
pageParam,
|
|
212
|
-
nextPageParam,
|
|
213
|
-
initialPageParam,
|
|
214
|
-
})
|
|
215
|
-
: undefined;
|
|
216
|
-
const hookWithJsDoc = addJSDocToNode(queryHook, jsDoc);
|
|
217
|
-
const suspenseHookWithJsDoc = addJSDocToNode(suspenseQueryHook, jsDoc);
|
|
218
|
-
const infiniteHookWithJsDoc = infiniteQueryHook
|
|
219
|
-
? addJSDocToNode(infiniteQueryHook, jsDoc)
|
|
220
|
-
: undefined;
|
|
221
|
-
const returnTypeExport = createReturnTypeExport({
|
|
222
|
-
methodName,
|
|
223
|
-
defaultApiResponse,
|
|
224
|
-
});
|
|
225
|
-
const queryKeyExport = createQueryKeyExport({
|
|
226
|
-
methodName,
|
|
227
|
-
queryKey,
|
|
228
|
-
});
|
|
229
|
-
const queryKeyFn = createQueryKeyFnExport(queryKey, method, "query", modelNames);
|
|
230
|
-
return {
|
|
231
|
-
apiResponse: defaultApiResponse,
|
|
232
|
-
returnType: returnTypeExport,
|
|
233
|
-
key: queryKeyExport,
|
|
234
|
-
queryHook: hookWithJsDoc,
|
|
235
|
-
suspenseQueryHook: suspenseHookWithJsDoc,
|
|
236
|
-
infiniteQueryHook: infiniteHookWithJsDoc,
|
|
237
|
-
queryKeyFn,
|
|
238
|
-
};
|
|
239
|
-
};
|
|
240
|
-
function createInfiniteQueryParams(pageParam, nextPageParam, initialPageParam = "1") {
|
|
241
|
-
if (pageParam === undefined || nextPageParam === undefined) {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
return [
|
|
245
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("initialPageParam"), ts.factory.createStringLiteral(initialPageParam)),
|
|
246
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("getNextPageParam"),
|
|
247
|
-
// (response) => (response as { nextPage: number }).nextPage,
|
|
248
|
-
ts.factory.createArrowFunction(undefined, undefined, [
|
|
249
|
-
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("response"), undefined, undefined),
|
|
250
|
-
], undefined, EqualsOrGreaterThanToken, ts.factory.createPropertyAccessExpression(ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(ts.factory.createIdentifier("response"), nextPageParam.split(".").reduceRight((acc, segment) => {
|
|
251
|
-
return ts.factory.createTypeLiteralNode([
|
|
252
|
-
ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(segment), undefined, acc),
|
|
253
|
-
]);
|
|
254
|
-
}, ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)))), ts.factory.createIdentifier(nextPageParam)))),
|
|
255
|
-
];
|
|
256
|
-
}
|