@7nohe/openapi-react-query-codegen
Version:
OpenAPI React Query Codegen
77 lines (76 loc) • 5.91 kB
JavaScript
import ts from "typescript";
import { BuildCommonTypeName, TContext, TData, TError, capitalizeFirstLetter, extractPropertiesFromObjectParam, getNameFromMethod, getShortType, } from "./common.mjs";
import { addJSDocToNode } from "./util.mjs";
/**
* Awaited<ReturnType<typeof myClass.myMethod>>
*/
function generateAwaitedReturnType({ className, methodName, }) {
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Awaited"), [
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("ReturnType"), [
ts.factory.createTypeQueryNode(ts.factory.createQualifiedName(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined),
]),
]);
}
export const createUseMutation = ({ className, method, jsDoc, }) => {
const methodName = getNameFromMethod(method);
const awaitedResponseDataType = generateAwaitedReturnType({
className,
methodName,
});
const mutationResult = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${className}${capitalizeFirstLetter(methodName)}MutationResult`), undefined, awaitedResponseDataType);
const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(mutationResult.name)));
const methodParameters = method.getParameters().length !== 0
? ts.factory.createTypeLiteralNode(method.getParameters().flatMap((param) => {
const paramNodes = extractPropertiesFromObjectParam(param);
return paramNodes.map((refParam) => ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(refParam.name), refParam.optional
? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
: undefined, ts.factory.createTypeReferenceNode(getShortType(refParam.type?.getText(param) ?? ""))));
}))
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
const exportHook = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
ts.factory.createVariableDeclaration(ts.factory.createIdentifier(`use${className}${capitalizeFirstLetter(methodName)}`), undefined, undefined, ts.factory.createArrowFunction(undefined, ts.factory.createNodeArray([
responseDataType,
ts.factory.createTypeParameterDeclaration(undefined, TError, undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)),
ts.factory.createTypeParameterDeclaration(undefined, TContext, undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)),
]), [
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("options"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Omit"), [
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("UseMutationOptions"), [
ts.factory.createTypeReferenceNode(TData),
ts.factory.createTypeReferenceNode(TError),
methodParameters,
ts.factory.createTypeReferenceNode(TContext),
]),
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("mutationFn")),
]), undefined),
], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression(ts.factory.createIdentifier("useMutation"), [
ts.factory.createTypeReferenceNode(TData),
ts.factory.createTypeReferenceNode(TError),
methodParameters,
ts.factory.createTypeReferenceNode(TContext),
], [
ts.factory.createObjectLiteralExpression([
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("mutationFn"), ts.factory.createArrowFunction(undefined, undefined, method.getParameters().length !== 0
? [
ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern(method.getParameters().flatMap((param) => {
const paramNodes = extractPropertiesFromObjectParam(param);
return paramNodes.map((refParam) => ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(refParam.name), undefined));
})), undefined, undefined, undefined),
]
: [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createAsExpression(ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length !== 0
? [
ts.factory.createObjectLiteralExpression(method.getParameters().flatMap((params) => {
const paramNodes = extractPropertiesFromObjectParam(params);
return paramNodes.map((refParam) => ts.factory.createShorthandPropertyAssignment(refParam.name));
})),
]
: []), ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Promise"), [ts.factory.createTypeReferenceNode(TData)])))),
ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
]),
]))),
], ts.NodeFlags.Const));
const hookWithJsDoc = addJSDocToNode(exportHook, jsDoc);
return {
mutationResult,
mutationHook: hookWithJsDoc,
};
};