From 0ca5fd5d18eeeed3bbe0a5f8f791d62836174337 Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Fri, 20 Feb 2026 19:10:57 +0700 Subject: [PATCH 01/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20add=20axios=20class=20draft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/apicraft.config.ts | 4 +- packages/apicraft/bin/generate.ts | 13 ++ packages/apicraft/bin/helpers/index.ts | 1 + packages/apicraft/bin/plugins/axios/plugin.ts | 161 +++----------- .../apicraft/bin/plugins/axiosClass/config.ts | 18 ++ .../apicraft/bin/plugins/axiosClass/index.ts | 2 + .../apicraft/bin/plugins/axiosClass/plugin.ts | 204 ++++++++++++++++++ .../bin/plugins/axiosClass/types.d.ts | 14 ++ .../axios/getAxiosRequestCallExpression.ts | 78 +++++++ .../getAxiosRequestParameterDeclaration.ts | 66 ++++++ .../axios/getAxiosRequestParamsType.ts | 23 ++ .../axios/getImportAxiosRequestParams.ts | 19 ++ .../bin/plugins/helpers/axios/index.ts | 4 + .../helpers/checkRequestHasRequiredParam.ts | 2 +- .../bin/plugins/helpers/getRequestInfo.ts | 24 +++ .../apicraft/bin/plugins/helpers/index.ts | 2 + packages/apicraft/bin/schemas/index.ts | 2 +- .../hooks/Echo/usePostEchoMutation.gen.ts | 13 ++ .../apiV1/hooks/Echo/usePostEchoQuery.gen.ts | 13 ++ .../Echo/usePostEchoSuspenseQuery.gen.ts | 15 ++ .../User/usePutUserByUsernameMutation.gen.ts | 13 ++ .../User/usePutUserByUsernameQuery.gen.ts | 13 ++ .../usePutUserByUsernameSuspenseQuery.gen.ts | 15 ++ .../hooks/default/useGetUsersMutation.gen.ts | 14 ++ .../hooks/default/useGetUsersQuery.gen.ts | 13 ++ .../default/useGetUsersSuspenseQuery.gen.ts | 15 ++ packages/apicraft/generated/apiV1/index.ts | 12 ++ .../apicraft/generated/apiV1/instance.gen.ts | 53 +++++ .../apicraft/generated/apiV1/types.gen.ts | 115 ++++++++++ 29 files changed, 800 insertions(+), 141 deletions(-) create mode 100644 packages/apicraft/bin/plugins/axiosClass/config.ts create mode 100644 packages/apicraft/bin/plugins/axiosClass/index.ts create mode 100644 packages/apicraft/bin/plugins/axiosClass/plugin.ts create mode 100644 packages/apicraft/bin/plugins/axiosClass/types.d.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/index.ts create mode 100644 packages/apicraft/bin/plugins/helpers/getRequestInfo.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV1/index.ts create mode 100644 packages/apicraft/generated/apiV1/instance.gen.ts create mode 100644 packages/apicraft/generated/apiV1/types.gen.ts diff --git a/packages/apicraft/apicraft.config.ts b/packages/apicraft/apicraft.config.ts index 75b9455..c9058bb 100644 --- a/packages/apicraft/apicraft.config.ts +++ b/packages/apicraft/apicraft.config.ts @@ -6,9 +6,9 @@ import { apicraft } from './dist/esm/index.mjs'; const apicraftConfig = apicraft([ { - input: 'example-apiV1.yaml', + input: 'example-apiV2.yaml', output: 'generated/apiV1', - instance: 'fetches', + instance: 'axios/class', nameBy: 'path', groupBy: 'tag', plugins: ['tanstack'] diff --git a/packages/apicraft/bin/generate.ts b/packages/apicraft/bin/generate.ts index 5941dc9..c2cc71a 100644 --- a/packages/apicraft/bin/generate.ts +++ b/packages/apicraft/bin/generate.ts @@ -9,6 +9,7 @@ import { getConfig } from '@/bin/helpers'; import type { ApicraftOption, GenerateApicraftOption, InstanceName } from './schemas'; import { defineAxiosPlugin } from './plugins/axios'; +import { defineAxiosClassPlugin } from './plugins/axiosClass'; import { defineFetchesPlugin } from './plugins/fetches'; import { defineTanstackPlugin } from './plugins/tanstack'; import { apicraftConfigSchema, apicraftOptionSchema } from './schemas'; @@ -66,6 +67,18 @@ export const generate = { ); } + if (matchInstance('axios/class')) { + plugins.push( + defineAxiosClassPlugin({ + generateOutput: + typeof option.output === 'string' ? option.output : option.output.path, + exportFromIndex: true, + nameBy: option.nameBy, + groupBy: option.groupBy + }) + ); + } + const generateOutput = typeof option.output === 'string' ? option.output : option.output.path; diff --git a/packages/apicraft/bin/helpers/index.ts b/packages/apicraft/bin/helpers/index.ts index f478f5c..5cf2093 100644 --- a/packages/apicraft/bin/helpers/index.ts +++ b/packages/apicraft/bin/helpers/index.ts @@ -1 +1,2 @@ +export * from '../plugins/helpers/getRequestInfo'; export * from './getConfig'; diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index 94ecfe7..a8d15a2 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -4,11 +4,14 @@ import ts from 'typescript'; import type { AxiosPlugin } from './types'; import { - buildRequestParamsPath, capitalize, - checkRequestHasRequiredParam, generateRequestName, - getRequestFilePaths + getAxiosRequestCallExpression, + getAxiosRequestParameterDeclaration, + getAxiosRequestParamsType, + getImportAxiosRequestParams, + getRequestFilePaths, + getRequestInfo } from '../helpers'; import { addInstanceFile } from './helpers'; @@ -19,6 +22,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { if (event.type !== 'operation') return; const request = event.operation; + const requestInfo = getRequestInfo({ request }); const requestName = generateRequestName(request, plugin.config.nameBy); const requestFilePaths = getRequestFilePaths({ @@ -38,26 +42,8 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { const requestDataTypeName = `${capitalize(request.id)}Data`; const requestResponseTypeName = `${capitalize(request.id)}Response`; - // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; - const importAxiosRequestParams = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - true, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier('AxiosRequestParams') - ) - ]) - ), - ts.factory.createStringLiteral('@siberiacancode/apicraft') - ); + const importAxiosRequestParams = getImportAxiosRequestParams(); - const requestHasResponse = Object.values(request.responses ?? {}).some( - (response) => response?.schema.$ref || response?.schema.type !== 'unknown' - ); const requestFolderPath = nodePath.dirname( `${plugin.config.generateOutput}/${requestFilePath}` ); @@ -74,7 +60,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { undefined, ts.factory.createIdentifier(requestDataTypeName) ), - ...(requestHasResponse + ...(requestInfo.hasResponse ? [ ts.factory.createImportSpecifier( false, @@ -116,21 +102,10 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { ) ); - // type RequestParams = AxiosRequestParams; - const requestParamsType = ts.factory.createTypeAliasDeclaration( - [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], - ts.factory.createIdentifier(requestParamsTypeName), - undefined, - ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('AxiosRequestParams'), [ - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier(requestDataTypeName), - undefined - ) - ]) - ); - - const requestHasPathParam = !!Object.keys(request.parameters?.path ?? {}).length; - const requestHasRequiredParam = checkRequestHasRequiredParam(request); + const requestParamsType = getAxiosRequestParamsType({ + requestDataTypeName, + requestParamsTypeName + }); // --- export const request = ({ path, body, query, config }) => ... const requestFunction = ts.factory.createVariableStatement( @@ -145,108 +120,20 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { undefined, undefined, [ - ts.factory.createParameterDeclaration( - undefined, - undefined, - ts.factory.createObjectBindingPattern([ - ts.factory.createBindingElement( - undefined, - undefined, - ts.factory.createIdentifier('config'), - undefined - ), - ...(request.body - ? [ - ts.factory.createBindingElement( - undefined, - undefined, - ts.factory.createIdentifier('body'), - undefined - ) - ] - : []), - ...(request.parameters?.query - ? [ - ts.factory.createBindingElement( - undefined, - undefined, - ts.factory.createIdentifier('query'), - undefined - ) - ] - : []), - - ...(requestHasPathParam - ? [ - ts.factory.createBindingElement( - undefined, - undefined, - ts.factory.createIdentifier('path'), - undefined - ) - ] - : []) - ]), - undefined, - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier(requestParamsTypeName), - undefined - ), - !requestHasRequiredParam - ? ts.factory.createObjectLiteralExpression([], false) - : undefined - ) + getAxiosRequestParameterDeclaration({ + request, + requestInfo, + requestParamsTypeName + }) ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier('instance'), - ts.factory.createIdentifier('request') - ), - requestHasResponse - ? [ - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier(requestResponseTypeName), - undefined - ) - ] - : undefined, - [ - ts.factory.createObjectLiteralExpression( - [ - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier('method'), - ts.factory.createStringLiteral(request.method.toUpperCase()) - ), - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier('url'), - requestHasPathParam - ? buildRequestParamsPath(request.path) - : ts.factory.createStringLiteral(request.path) - ), - ...(request.body - ? [ - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier('data'), - ts.factory.createIdentifier('body') - ) - ] - : []), - ...(request.parameters?.query - ? [ - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier('params'), - ts.factory.createIdentifier('query') - ) - ] - : []), - ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')) - ], - true - ) - ] - ) + getAxiosRequestCallExpression({ + request, + requestInfo, + requestResponseTypeName, + variant: 'function' + }) ) ) ], diff --git a/packages/apicraft/bin/plugins/axiosClass/config.ts b/packages/apicraft/bin/plugins/axiosClass/config.ts new file mode 100644 index 0000000..f1595e5 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/config.ts @@ -0,0 +1,18 @@ +import { definePluginConfig } from '@hey-api/openapi-ts'; + +import type { AxiosClassPlugin } from './types'; + +import { handler } from './plugin'; + +export const defaultConfig: AxiosClassPlugin['Config'] = { + config: { + generateOutput: '', + exportFromIndex: true + }, + dependencies: ['@hey-api/typescript'], + handler, + name: 'axiosClass', + output: '.' +}; + +export const defineAxiosClassPlugin = definePluginConfig(defaultConfig); diff --git a/packages/apicraft/bin/plugins/axiosClass/index.ts b/packages/apicraft/bin/plugins/axiosClass/index.ts new file mode 100644 index 0000000..f03d024 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/index.ts @@ -0,0 +1,2 @@ +export { defineAxiosClassPlugin } from './config'; +export type { AxiosClassPlugin } from './types'; diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axiosClass/plugin.ts new file mode 100644 index 0000000..58bb021 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/plugin.ts @@ -0,0 +1,204 @@ +import type { IR } from '@hey-api/openapi-ts'; + +import * as nodePath from 'node:path'; +import ts from 'typescript'; + +import {} from '@/bin/helpers'; + +import type { AxiosClassPlugin } from './types'; + +import { + capitalize, + generateRequestName, + getAxiosRequestCallExpression, + getAxiosRequestParameterDeclaration, + getAxiosRequestParamsType, + getImportAxiosRequestParams, + getRequestInfo +} from '../helpers'; + +interface RequestMeta { + request: IR.OperationObject; + requestName: string; +} + +const CLASS_NAME = 'ApiInstance'; + +export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { + const requests: RequestMeta[] = []; + + plugin.forEach('operation', (event) => { + if (event.type !== 'operation') return; + + const request = event.operation; + const requestName = generateRequestName(request, plugin.config.nameBy); + + requests.push({ request, requestName }); + }); + if (!requests.length) return; + + const classFilePath = nodePath.normalize(`${plugin.output}/instance`); + const classFile = plugin.createFile({ + id: 'axiosInstance', + path: classFilePath + }); + + const classFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${classFilePath}`); + + const typeImportNames = new Set(); + const typeAliases: ts.Statement[] = []; + const classMembers: ts.ClassElement[] = []; + + requests.forEach(({ request, requestName }) => { + const requestInfo = getRequestInfo({ request }); + + const requestDataTypeName = `${capitalize(request.id)}Data`; + typeImportNames.add(requestDataTypeName); + + const requestResponseTypeName = `${capitalize(request.id)}Response`; + if (requestInfo.hasResponse) typeImportNames.add(requestResponseTypeName); + + const requestParamsTypeName = `${capitalize(requestName)}RequestParams`; + typeAliases.push( + getAxiosRequestParamsType({ + requestDataTypeName, + requestParamsTypeName + }) + ); + + const requestParameter = getAxiosRequestParameterDeclaration({ + request, + requestInfo, + requestParamsTypeName + }); + + const requestBody = ts.factory.createBlock( + [ + ts.factory.createReturnStatement( + getAxiosRequestCallExpression({ + request, + requestInfo, + requestResponseTypeName, + variant: 'class' + }) + ) + ], + true + ); + + classMembers.push( + ts.factory.createMethodDeclaration( + undefined, + undefined, + ts.factory.createIdentifier(requestName), + undefined, + undefined, + [requestParameter], + undefined, + requestBody + ) + ); + }); + + const importAxiosRequestParams = getImportAxiosRequestParams(); + + const importTypes = ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + true, + undefined, + ts.factory.createNamedImports( + Array.from(typeImportNames).map((specifier) => + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(specifier)) + ) + ) + ), + ts.factory.createStringLiteral( + nodePath.relative( + classFolderPath, + nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) + ) + ) + ); + + const importAxios = ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + ts.factory.createIdentifier('axios'), + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier('AxiosInstance') + ) + ]) + ), + ts.factory.createStringLiteral('axios') + ); + + const classInstanceProperty = ts.factory.createPropertyDeclaration( + [ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)], + ts.factory.createIdentifier('instance'), + undefined, + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('AxiosInstance'), undefined), + undefined + ); + + const constructorDeclaration = ts.factory.createConstructorDeclaration( + undefined, + [], + ts.factory.createBlock( + [ + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createThis(), + ts.factory.createIdentifier('instance') + ), + ts.factory.createToken(ts.SyntaxKind.EqualsToken), + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('axios'), + ts.factory.createIdentifier('create') + ), + undefined, + undefined + ) + ) + ) + ], + true + ) + ); + + const classDeclaration = ts.factory.createClassDeclaration( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createIdentifier(CLASS_NAME), + undefined, + undefined, + [classInstanceProperty, constructorDeclaration, ...classMembers] + ); + + const classInstance = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier('instance'), + undefined, + undefined, + ts.factory.createNewExpression(ts.factory.createIdentifier(CLASS_NAME), undefined, []) + ) + ], + ts.NodeFlags.Const + ) + ); + + classFile.add(importAxiosRequestParams); + classFile.add(importTypes); + classFile.add(importAxios); + typeAliases.forEach((alias) => classFile.add(alias)); + classFile.add(classDeclaration); + classFile.add(classInstance); +}; diff --git a/packages/apicraft/bin/plugins/axiosClass/types.d.ts b/packages/apicraft/bin/plugins/axiosClass/types.d.ts new file mode 100644 index 0000000..7afeb48 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/types.d.ts @@ -0,0 +1,14 @@ +import type { DefinePlugin } from '@hey-api/openapi-ts'; + +import type { ApicraftOption } from '@/bin/schemas'; + +export interface AxiosClassPluginConfig { + exportFromIndex: boolean; + generateOutput: string; + groupBy?: ApicraftOption['groupBy']; + name: 'axiosClass'; + nameBy?: ApicraftOption['nameBy']; + output?: string; +} + +export type AxiosClassPlugin = DefinePlugin; diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts new file mode 100644 index 0000000..90efb4c --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts @@ -0,0 +1,78 @@ +import type { IR } from '@hey-api/openapi-ts'; + +import ts from 'typescript'; + +import type { GetRequestInfoResult } from '../getRequestInfo'; + +import { buildRequestParamsPath } from '../buildRequestParamsPath'; + +interface GetAxiosRequestCallExpressionParams { + request: IR.OperationObject; + requestInfo: GetRequestInfoResult; + requestResponseTypeName: string; + variant: 'class' | 'function'; +} + +// instance.request({ method, url, data, params }) +export const getAxiosRequestCallExpression = ({ + request, + requestInfo, + requestResponseTypeName, + variant +}: GetAxiosRequestCallExpressionParams) => + ts.factory.createCallExpression( + variant === 'class' + ? ts.factory.createPropertyAccessExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createThis(), + ts.factory.createIdentifier('instance') + ), + ts.factory.createIdentifier('request') + ) + : ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier('request') + ), + requestInfo.hasResponse + ? [ + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier(requestResponseTypeName), + undefined + ) + ] + : undefined, + [ + ts.factory.createObjectLiteralExpression( + [ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('method'), + ts.factory.createStringLiteral(request.method.toUpperCase()) + ), + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('url'), + requestInfo.hasPathParam + ? buildRequestParamsPath(request.path) + : ts.factory.createStringLiteral(request.path) + ), + ...(request.body + ? [ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('data'), + ts.factory.createIdentifier('body') + ) + ] + : []), + ...(request.parameters?.query + ? [ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('params'), + ts.factory.createIdentifier('query') + ) + ] + : []), + ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')) + ], + true + ) + ] + ); diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts new file mode 100644 index 0000000..f7550d8 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts @@ -0,0 +1,66 @@ +import type { IR } from '@hey-api/openapi-ts'; + +import ts from 'typescript'; + +import type { GetRequestInfoResult } from '../getRequestInfo'; + +interface GetAxiosRequestParameterDeclarationParams { + request: IR.OperationObject; + requestInfo: GetRequestInfoResult; + requestParamsTypeName: string; +} + +// ({ path, body, query, config }: RequestParams) +export const getAxiosRequestParameterDeclaration = ({ + request, + requestInfo, + requestParamsTypeName +}: GetAxiosRequestParameterDeclarationParams) => + ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createObjectBindingPattern([ + ts.factory.createBindingElement( + undefined, + undefined, + ts.factory.createIdentifier('config'), + undefined + ), + ...(request.body + ? [ + ts.factory.createBindingElement( + undefined, + undefined, + ts.factory.createIdentifier('body'), + undefined + ) + ] + : []), + ...(request.parameters?.query + ? [ + ts.factory.createBindingElement( + undefined, + undefined, + ts.factory.createIdentifier('query'), + undefined + ) + ] + : []), + ...(requestInfo.hasPathParam + ? [ + ts.factory.createBindingElement( + undefined, + undefined, + ts.factory.createIdentifier('path'), + undefined + ) + ] + : []) + ]), + undefined, + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier(requestParamsTypeName), + undefined + ), + !requestInfo.hasRequiredParam ? ts.factory.createObjectLiteralExpression([], false) : undefined + ); diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts new file mode 100644 index 0000000..f3646a2 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts @@ -0,0 +1,23 @@ +import ts from 'typescript'; + +interface GetAxiosRequestParamsTypeParams { + requestDataTypeName: string; + requestParamsTypeName: string; +} + +// type RequestParams = AxiosRequestParams; +export const getAxiosRequestParamsType = ({ + requestDataTypeName, + requestParamsTypeName +}: GetAxiosRequestParamsTypeParams) => + ts.factory.createTypeAliasDeclaration( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createIdentifier(requestParamsTypeName), + undefined, + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('AxiosRequestParams'), [ + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier(requestDataTypeName), + undefined + ) + ]) + ); diff --git a/packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts b/packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts new file mode 100644 index 0000000..2726eb6 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts @@ -0,0 +1,19 @@ +import ts from 'typescript'; + +// import type { AxiosRequestParams } from '@siberiacancode/apicraft'; +export const getImportAxiosRequestParams = () => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + true, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier('AxiosRequestParams') + ) + ]) + ), + ts.factory.createStringLiteral('@siberiacancode/apicraft') + ); diff --git a/packages/apicraft/bin/plugins/helpers/axios/index.ts b/packages/apicraft/bin/plugins/helpers/axios/index.ts new file mode 100644 index 0000000..f3ec096 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/index.ts @@ -0,0 +1,4 @@ +export * from './getAxiosRequestCallExpression'; +export * from './getAxiosRequestParameterDeclaration'; +export * from './getAxiosRequestParamsType'; +export * from './getImportAxiosRequestParams'; diff --git a/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts b/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts index 6c986d2..c9110c8 100644 --- a/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts +++ b/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts @@ -3,4 +3,4 @@ import type { IR } from '@hey-api/openapi-ts'; export const checkRequestHasRequiredParam = (request: IR.OperationObject) => Object.values(request.parameters?.query ?? {}).some((queryParam) => queryParam.required) || Object.values(request.parameters?.path ?? {}).some((pathParam) => pathParam.required) || - request.body?.required; + !!request.body?.required; diff --git a/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts b/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts new file mode 100644 index 0000000..11e53ec --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts @@ -0,0 +1,24 @@ +import type { IR } from '@hey-api/openapi-ts'; + +interface GetRequestInfoParams { + request: IR.OperationObject; +} + +export interface GetRequestInfoResult { + hasPathParam: boolean; + hasRequiredParam: boolean; + hasResponse: boolean; +} + +export const getRequestInfo = ({ request }: GetRequestInfoParams): GetRequestInfoResult => { + return { + hasResponse: Object.values(request.responses ?? {}).some( + (response) => response?.schema.$ref || response?.schema.type !== 'unknown' + ), + hasPathParam: !!Object.keys(request.parameters?.path ?? {}).length, + hasRequiredParam: + Object.values(request.parameters?.query ?? {}).some((queryParam) => queryParam.required) || + Object.values(request.parameters?.path ?? {}).some((pathParam) => pathParam.required) || + !!request.body?.required + }; +}; diff --git a/packages/apicraft/bin/plugins/helpers/index.ts b/packages/apicraft/bin/plugins/helpers/index.ts index 3ed8094..91e6e0c 100644 --- a/packages/apicraft/bin/plugins/helpers/index.ts +++ b/packages/apicraft/bin/plugins/helpers/index.ts @@ -1,6 +1,8 @@ +export * from './axios'; export * from './buildRequestParamsPath'; export * from './capitalize'; export * from './checkRequestHasRequiredParam'; export * from './generatePathRequestName'; export * from './generateRequestName'; export * from './getRequestFilePaths'; +export * from './getRequestInfo'; diff --git a/packages/apicraft/bin/schemas/index.ts b/packages/apicraft/bin/schemas/index.ts index f3571f1..65e6fa9 100644 --- a/packages/apicraft/bin/schemas/index.ts +++ b/packages/apicraft/bin/schemas/index.ts @@ -1,6 +1,6 @@ import * as z from 'zod'; -const instanceNameSchema = z.enum(['fetches', 'axios']); +const instanceNameSchema = z.enum(['fetches', 'axios', 'fetches/class', 'axios/class']); const instanceSchema = z.object({ name: instanceNameSchema, runtimeInstancePath: z.string().optional() diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts new file mode 100644 index 0000000..5143644 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { postEcho } from "../../requests/Echo/postEcho.gen"; + +export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["postEcho"], + mutationFn: async (params) => postEcho({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts new file mode 100644 index 0000000..a4ba9a7 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { postEcho } from "../../requests/Echo/postEcho.gen"; + +export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["postEcho"], + queryFn: async () => postEcho({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts new file mode 100644 index 0000000..7e3c743 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { postEcho } from "../../requests/Echo/postEcho.gen"; + +export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["postEcho"], + queryFn: async () => postEcho({ ...settings.request }), + ...settings.params +}); + +export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts new file mode 100644 index 0000000..84aa5bb --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; + +export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["putUserByUsername", settings?.request?.path?.username], + mutationFn: async (params) => putUserByUsername({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts new file mode 100644 index 0000000..d49bce1 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; + +export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["putUserByUsername", settings.request.path?.username], + queryFn: async () => putUserByUsername({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts new file mode 100644 index 0000000..43b6b09 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; + +export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["putUserByUsername", settings.request.path?.username], + queryFn: async () => putUserByUsername({ ...settings.request }), + ...settings.params +}); + +export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts new file mode 100644 index 0000000..8542518 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts @@ -0,0 +1,14 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from '@tanstack/react-query'; + +import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; + +import { getUsers } from '../../requests/default/getUsers.gen'; + +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => + useMutation({ + mutationKey: ['getUsers'], + mutationFn: async (params) => getUsers({ ...settings?.request, ...params }), + ...settings?.params + }); diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts new file mode 100644 index 0000000..76255fc --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { getUsers } from "../../requests/default/getUsers.gen"; + +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ + queryKey: ["getUsers"], + queryFn: async () => getUsers({ ...settings?.request }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts new file mode 100644 index 0000000..b4d6b22 --- /dev/null +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { getUsers } from "../../requests/default/getUsers.gen"; + +export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["getUsers"], + queryFn: async () => getUsers({ ...settings?.request }), + ...settings?.params +}); + +export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/index.ts b/packages/apicraft/generated/apiV1/index.ts new file mode 100644 index 0000000..75b106f --- /dev/null +++ b/packages/apicraft/generated/apiV1/index.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './types.gen'; +export * from './hooks/default/useGetUsersQuery.gen'; +export * from './hooks/default/useGetUsersSuspenseQuery.gen'; +export * from './hooks/default/useGetUsersMutation.gen'; +export * from './hooks/User/usePutUserByUsernameQuery.gen'; +export * from './hooks/User/usePutUserByUsernameSuspenseQuery.gen'; +export * from './hooks/User/usePutUserByUsernameMutation.gen'; +export * from './hooks/Echo/usePostEchoQuery.gen'; +export * from './hooks/Echo/usePostEchoSuspenseQuery.gen'; +export * from './hooks/Echo/usePostEchoMutation.gen'; +export * from './instance.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/instance.gen.ts b/packages/apicraft/generated/apiV1/instance.gen.ts new file mode 100644 index 0000000..7faeb07 --- /dev/null +++ b/packages/apicraft/generated/apiV1/instance.gen.ts @@ -0,0 +1,53 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosRequestParams } from '@siberiacancode/apicraft'; + +import type { + GetUserByNameData, + GetUserByNameResponse, + UpdateUserData, + EchoData, + EchoResponse +} from './types.gen'; + +import axios, { AxiosInstance } from 'axios'; + +export type GetUsersRequestParams = AxiosRequestParams; + +export type PutUserByUsernameRequestParams = AxiosRequestParams; + +export type PostEchoRequestParams = AxiosRequestParams; + +export class ApiInstance { + private instance: AxiosInstance; + constructor() { + this.instance = axios.create(); + } + getUsers({ config, query }: GetUsersRequestParams = {}) { + return this.instance.request({ + method: 'GET', + url: '/users', + params: query, + ...config + }); + } + putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { + return this.instance.request({ + method: 'PUT', + url: `/users/${path.username}`, + data: body, + params: query, + ...config + }); + } + postEcho({ config, body }: PostEchoRequestParams) { + return this.instance.request({ + method: 'POST', + url: '/echo', + data: body, + ...config + }); + } +} + +export const instance = new ApiInstance(); diff --git a/packages/apicraft/generated/apiV1/types.gen.ts b/packages/apicraft/generated/apiV1/types.gen.ts new file mode 100644 index 0000000..bfb2c6e --- /dev/null +++ b/packages/apicraft/generated/apiV1/types.gen.ts @@ -0,0 +1,115 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * User email address + */ +export type Email = string; + +export type User = { + /** + * User supplied username + */ + username?: string; + /** + * User first name + */ + firstName?: string; + /** + * User last name + */ + lastName?: string; + email?: Email; +}; + +export type GetUserByNameData = { + body?: never; + path?: never; + query?: { + /** + * Filter users without email + */ + with_email?: boolean; + }; + url: '/users'; +}; + +export type GetUserByNameErrors = { + /** + * Forbidden + */ + 403: unknown; + /** + * User not found + */ + 404: unknown; +}; + +export type GetUserByNameResponses = { + /** + * Success + */ + 200: User; +}; + +export type GetUserByNameResponse = GetUserByNameResponses[keyof GetUserByNameResponses]; + +export type UpdateUserData = { + /** + * Updated user object + */ + body: User; + path: { + /** + * The name that needs to be updated + */ + username: string; + }; + query?: { + /** + * Pretty print response + */ + pretty_print?: boolean; + }; + url: '/users/{username}'; +}; + +export type UpdateUserErrors = { + /** + * Invalid user supplied + */ + 400: unknown; + /** + * User not found + */ + 404: unknown; +}; + +export type UpdateUserResponses = { + /** + * OK + */ + 200: unknown; +}; + +export type EchoData = { + /** + * Echo payload + */ + body: string; + path?: never; + query?: never; + url: '/echo'; +}; + +export type EchoResponses = { + /** + * OK + */ + 200: string; +}; + +export type EchoResponse = EchoResponses[keyof EchoResponses]; + +export type ClientOptions = { + baseUrl: 'http://example.com/api/v1' | 'https://example.com/api/v1' | (string & {}); +}; \ No newline at end of file From d3a4ba1d12397aad00cd83be1966577c8ac3e065 Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 21 Feb 2026 15:51:05 +0700 Subject: [PATCH 02/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20support=20class=20variant=20for=20tanstack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/bin/generate.ts | 6 +- packages/apicraft/bin/plugins/axios/plugin.ts | 39 ++------- .../apicraft/bin/plugins/axiosClass/plugin.ts | 83 ++++++++++--------- .../apicraft/bin/plugins/fetches/plugin.ts | 38 ++------- .../helpers/imports/getImportInstance.ts | 31 +++++++ .../helpers/imports/getImportRequest.ts | 26 ++++++ .../bin/plugins/helpers/imports/index.ts | 2 + .../apicraft/bin/plugins/helpers/index.ts | 2 + .../apicraft/bin/plugins/tanstack/config.ts | 3 +- .../helpers/generateMutationHookFile.ts | 58 +++++++++---- .../tanstack/helpers/generateQueryHookFile.ts | 63 ++++++++++---- .../helpers/generateSuspenseQueryHookFile.ts | 63 ++++++++++---- .../apicraft/bin/plugins/tanstack/types.d.ts | 2 + .../hooks/Echo/usePostEchoMutation.gen.ts | 6 +- .../apiV1/hooks/Echo/usePostEchoQuery.gen.ts | 6 +- .../Echo/usePostEchoSuspenseQuery.gen.ts | 6 +- .../User/usePutUserByUsernameMutation.gen.ts | 6 +- .../User/usePutUserByUsernameQuery.gen.ts | 6 +- .../usePutUserByUsernameSuspenseQuery.gen.ts | 6 +- .../hooks/default/useGetUsersMutation.gen.ts | 15 ++-- .../hooks/default/useGetUsersQuery.gen.ts | 6 +- .../default/useGetUsersSuspenseQuery.gen.ts | 6 +- .../apicraft/generated/apiV1/instance.gen.ts | 6 +- 23 files changed, 295 insertions(+), 190 deletions(-) create mode 100644 packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts create mode 100644 packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts create mode 100644 packages/apicraft/bin/plugins/helpers/imports/index.ts diff --git a/packages/apicraft/bin/generate.ts b/packages/apicraft/bin/generate.ts index c2cc71a..8130e38 100644 --- a/packages/apicraft/bin/generate.ts +++ b/packages/apicraft/bin/generate.ts @@ -105,7 +105,11 @@ export const generate = { generateOutput, exportFromIndex: true, nameBy: option.nameBy, - groupBy: option.groupBy + groupBy: option.groupBy, + ...(typeof option.instance === 'object' && { + runtimeInstancePath: option.instance.runtimeInstancePath + }), + instanceVariant: matchInstance('axios/class') ? 'class' : 'function' }) ); } diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index a8d15a2..125ea54 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -10,6 +10,7 @@ import { getAxiosRequestParameterDeclaration, getAxiosRequestParamsType, getImportAxiosRequestParams, + getImportInstance, getRequestFilePaths, getRequestInfo } from '../helpers'; @@ -43,10 +44,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { const requestResponseTypeName = `${capitalize(request.id)}Response`; const importAxiosRequestParams = getImportAxiosRequestParams(); - - const requestFolderPath = nodePath.dirname( - `${plugin.config.generateOutput}/${requestFilePath}` - ); + const requestFolderPath = nodePath.dirname(requestFilePath); // import type { RequestData, RequestResponse } from 'generated/types.gen'; const importTypes = ts.factory.createImportDeclaration( @@ -72,35 +70,16 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { ]) ), ts.factory.createStringLiteral( - nodePath.relative( - requestFolderPath, - nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) - ) + nodePath.relative(requestFolderPath, nodePath.normalize('types.gen')) ) ); - // import { instance } from "generated/instance.gen"; - const importInstance = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier('instance') - ) - ]) - ), - ts.factory.createStringLiteral( - nodePath.relative( - requestFolderPath, - plugin.config.runtimeInstancePath ?? - nodePath.normalize(`${plugin.config.generateOutput}/${plugin.output}/instance.gen`) - ) - ) - ); + // import { instance } from "../../instance.gen"; + const importInstance = getImportInstance({ + folderPath: requestFolderPath, + output: plugin.output, + runtimeInstancePath: plugin.config.runtimeInstancePath + }); const requestParamsType = getAxiosRequestParamsType({ requestDataTypeName, diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axiosClass/plugin.ts index 58bb021..d58d09b 100644 --- a/packages/apicraft/bin/plugins/axiosClass/plugin.ts +++ b/packages/apicraft/bin/plugins/axiosClass/plugin.ts @@ -1,10 +1,6 @@ -import type { IR } from '@hey-api/openapi-ts'; - import * as nodePath from 'node:path'; import ts from 'typescript'; -import {} from '@/bin/helpers'; - import type { AxiosClassPlugin } from './types'; import { @@ -17,39 +13,24 @@ import { getRequestInfo } from '../helpers'; -interface RequestMeta { - request: IR.OperationObject; - requestName: string; -} - const CLASS_NAME = 'ApiInstance'; export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { - const requests: RequestMeta[] = []; - - plugin.forEach('operation', (event) => { - if (event.type !== 'operation') return; - - const request = event.operation; - const requestName = generateRequestName(request, plugin.config.nameBy); - - requests.push({ request, requestName }); - }); - if (!requests.length) return; - const classFilePath = nodePath.normalize(`${plugin.output}/instance`); const classFile = plugin.createFile({ id: 'axiosInstance', path: classFilePath }); - const classFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${classFilePath}`); - const typeImportNames = new Set(); - const typeAliases: ts.Statement[] = []; - const classMembers: ts.ClassElement[] = []; + const typeStatements: ts.Statement[] = []; + const classElements: ts.ClassElement[] = []; - requests.forEach(({ request, requestName }) => { + plugin.forEach('operation', (event) => { + if (event.type !== 'operation') return; + + const request = event.operation; + const requestName = generateRequestName(request, plugin.config.nameBy); const requestInfo = getRequestInfo({ request }); const requestDataTypeName = `${capitalize(request.id)}Data`; @@ -59,7 +40,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { if (requestInfo.hasResponse) typeImportNames.add(requestResponseTypeName); const requestParamsTypeName = `${capitalize(requestName)}RequestParams`; - typeAliases.push( + typeStatements.push( getAxiosRequestParamsType({ requestDataTypeName, requestParamsTypeName @@ -86,7 +67,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { true ); - classMembers.push( + classElements.push( ts.factory.createMethodDeclaration( undefined, undefined, @@ -102,25 +83,26 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { const importAxiosRequestParams = getImportAxiosRequestParams(); + // import type { RequestData, RequestResponse, ... } from './types.gen'; const importTypes = ts.factory.createImportDeclaration( undefined, ts.factory.createImportClause( true, undefined, ts.factory.createNamedImports( - Array.from(typeImportNames).map((specifier) => - ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(specifier)) + Array.from(typeImportNames).map((typeImportName) => + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier(typeImportName) + ) ) ) ), - ts.factory.createStringLiteral( - nodePath.relative( - classFolderPath, - nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) - ) - ) + ts.factory.createStringLiteral('./types.gen') ); + // import axios, { AxiosInstance, CreateAxiosDefaults } from 'axios'; const importAxios = ts.factory.createImportDeclaration( undefined, ts.factory.createImportClause( @@ -131,12 +113,18 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { false, undefined, ts.factory.createIdentifier('AxiosInstance') + ), + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier('CreateAxiosDefaults') ) ]) ), ts.factory.createStringLiteral('axios') ); + // private instance: AxiosInstance; const classInstanceProperty = ts.factory.createPropertyDeclaration( [ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)], ts.factory.createIdentifier('instance'), @@ -145,9 +133,22 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { undefined ); + // constructor(config?: CreateAxiosDefaults) { this.instance = axios.create(config); } const constructorDeclaration = ts.factory.createConstructorDeclaration( undefined, - [], + [ + ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier('config'), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier('CreateAxiosDefaults'), + undefined + ), + undefined + ) + ], ts.factory.createBlock( [ ts.factory.createExpressionStatement( @@ -163,7 +164,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { ts.factory.createIdentifier('create') ), undefined, - undefined + [ts.factory.createIdentifier('config')] ) ) ) @@ -172,14 +173,16 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { ) ); + // export class ApiInstance {...} const classDeclaration = ts.factory.createClassDeclaration( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(CLASS_NAME), undefined, undefined, - [classInstanceProperty, constructorDeclaration, ...classMembers] + [classInstanceProperty, constructorDeclaration, ...classElements] ); + // export const instance = new ApiInstance(); const classInstance = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( @@ -198,7 +201,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { classFile.add(importAxiosRequestParams); classFile.add(importTypes); classFile.add(importAxios); - typeAliases.forEach((alias) => classFile.add(alias)); + typeStatements.forEach((alias) => classFile.add(alias)); classFile.add(classDeclaration); classFile.add(classInstance); }; diff --git a/packages/apicraft/bin/plugins/fetches/plugin.ts b/packages/apicraft/bin/plugins/fetches/plugin.ts index bf6be5f..28f0114 100644 --- a/packages/apicraft/bin/plugins/fetches/plugin.ts +++ b/packages/apicraft/bin/plugins/fetches/plugin.ts @@ -8,6 +8,7 @@ import { capitalize, checkRequestHasRequiredParam, generateRequestName, + getImportInstance, getRequestFilePaths } from '../helpers'; import { addInstanceFile } from './helpers'; @@ -58,9 +59,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { const requestHasResponse = Object.values(request.responses ?? {}).some( (response) => response?.schema.$ref || response?.schema.type !== 'unknown' ); - const requestFolderPath = nodePath.dirname( - `${plugin.config.generateOutput}/${requestFilePath}` - ); + const requestFolderPath = nodePath.dirname(requestFilePath); // import type { RequestNameData, RequestNameResponse } from 'generated/types.gen'; const importTypes = ts.factory.createImportDeclaration( @@ -86,35 +85,16 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ]) ), ts.factory.createStringLiteral( - nodePath.relative( - requestFolderPath, - nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) - ) + nodePath.relative(requestFolderPath, nodePath.normalize('types.gen')) ) ); - // import { instance } from "generated/instance.gen"; - const importInstance = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier('instance') - ) - ]) - ), - ts.factory.createStringLiteral( - nodePath.relative( - requestFolderPath, - plugin.config.runtimeInstancePath ?? - nodePath.normalize(`${plugin.config.generateOutput}/${plugin.output}/instance.gen`) - ) - ) - ); + // import { instance } from "../../instance.gen"; + const importInstance = getImportInstance({ + folderPath: requestFolderPath, + output: plugin.output, + runtimeInstancePath: plugin.config.runtimeInstancePath + }); // type RequestNameParams = FetchesRequestParams; const requestParamsType = ts.factory.createTypeAliasDeclaration( diff --git a/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts new file mode 100644 index 0000000..bfd2046 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts @@ -0,0 +1,31 @@ +import nodePath from 'node:path'; +import ts from 'typescript'; + +interface GetImportInstanceParams { + folderPath: string; + output: string; + runtimeInstancePath?: string; +} + +// import { instance } from '../../instance.gen'; +export const getImportInstance = ({ + output, + runtimeInstancePath, + folderPath +}: GetImportInstanceParams) => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier('instance')) + ]) + ), + ts.factory.createStringLiteral( + nodePath.relative( + folderPath, + runtimeInstancePath ?? nodePath.normalize(`${output}/instance.gen`) + ) + ) + ); diff --git a/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts new file mode 100644 index 0000000..e6a2a5d --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts @@ -0,0 +1,26 @@ +import nodePath from 'node:path'; +import ts from 'typescript'; + +interface GetImportRequestParams { + hookFolderPath: string; + requestFilePath: string; + requestName: string; +} + +// import type { requestName } from './requestName.gen'; +export const getImportRequest = ({ + hookFolderPath, + requestFilePath, + requestName +}: GetImportRequestParams) => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(requestName)) + ]) + ), + ts.factory.createStringLiteral(nodePath.relative(hookFolderPath, `${requestFilePath}.gen`)) + ); diff --git a/packages/apicraft/bin/plugins/helpers/imports/index.ts b/packages/apicraft/bin/plugins/helpers/imports/index.ts new file mode 100644 index 0000000..84bfd29 --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/imports/index.ts @@ -0,0 +1,2 @@ +export * from './getImportInstance'; +export * from './getImportRequest'; diff --git a/packages/apicraft/bin/plugins/helpers/index.ts b/packages/apicraft/bin/plugins/helpers/index.ts index 91e6e0c..72313b3 100644 --- a/packages/apicraft/bin/plugins/helpers/index.ts +++ b/packages/apicraft/bin/plugins/helpers/index.ts @@ -6,3 +6,5 @@ export * from './generatePathRequestName'; export * from './generateRequestName'; export * from './getRequestFilePaths'; export * from './getRequestInfo'; +export * from './getRequestInfo'; +export * from './imports'; diff --git a/packages/apicraft/bin/plugins/tanstack/config.ts b/packages/apicraft/bin/plugins/tanstack/config.ts index b08ea2c..94b8836 100644 --- a/packages/apicraft/bin/plugins/tanstack/config.ts +++ b/packages/apicraft/bin/plugins/tanstack/config.ts @@ -7,7 +7,8 @@ import { handler } from './plugin'; export const defaultConfig: TanstackPlugin['Config'] = { config: { generateOutput: '', - exportFromIndex: true + exportFromIndex: true, + instanceVariant: 'function' }, dependencies: ['@hey-api/typescript'], handler, diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts index 0f74a70..7c92078 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts @@ -3,9 +3,10 @@ import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; import ts from 'typescript'; +import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; + import type { TanstackPluginConfig } from '../types'; -import { capitalize } from '../../helpers'; import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; interface GenerateMutationHookFileParams { @@ -23,7 +24,6 @@ export const generateMutationHookFile = ({ }: GenerateMutationHookFileParams) => { const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}Mutation`; - const hookFile = plugin.createFile({ id: `${hookFolderPath}/${hookName}`, path: `${hookFolderPath}/${hookName}` @@ -63,19 +63,6 @@ export const generateMutationHookFile = ({ ts.factory.createStringLiteral('@siberiacancode/apicraft') ); - // import type { requestName } from './requestName.gen'; - const importRequest = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(requestName)) - ]) - ), - ts.factory.createStringLiteral(nodePath.relative(hookFolderPath, `${requestFilePath}.gen`)) - ); - const requestParamsHookKeys = getRequestParamsHookKeys(request); // const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation @@ -98,7 +85,16 @@ export const generateMutationHookFile = ({ ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode( ts.factory.createIdentifier('TanstackMutationSettings'), - [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(requestName))] + [ + ts.factory.createTypeQueryNode( + plugin.config.instanceVariant === 'class' + ? ts.factory.createQualifiedName( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName) + ) + ] ) ) ], @@ -163,7 +159,12 @@ export const generateMutationHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - ts.factory.createIdentifier(requestName), + plugin.config.instanceVariant === 'class' + ? ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName), undefined, [ ts.factory.createObjectLiteralExpression( @@ -206,6 +207,27 @@ export const generateMutationHookFile = ({ hookFile.add(importUseMutation); hookFile.add(importTanstackMutationSettings); - hookFile.add(importRequest); + + if (plugin.config.instanceVariant === 'function') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + hookFolderPath, + requestFilePath, + requestName + }) + ); + } + if (plugin.config.instanceVariant === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + runtimeInstancePath: plugin.config.runtimeInstancePath + }) + ); + } + hookFile.add(hookFunction); }; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts index dde73cb..bc4778c 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts @@ -3,9 +3,15 @@ import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; import ts from 'typescript'; +import { + capitalize, + checkRequestHasRequiredParam, + getImportInstance, + getImportRequest +} from '@/bin/plugins/helpers'; + import type { TanstackPluginConfig } from '../types'; -import { capitalize, checkRequestHasRequiredParam } from '../../helpers'; import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; interface GenerateQueryHookParams { @@ -23,7 +29,6 @@ export const generateQueryHookFile = ({ }: GenerateQueryHookParams) => { const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}Query`; - const hookFile = plugin.createFile({ id: `${hookFolderPath}/${hookName}`, path: `${hookFolderPath}/${hookName}` @@ -59,19 +64,6 @@ export const generateQueryHookFile = ({ ts.factory.createStringLiteral('@siberiacancode/apicraft') ); - // import type { requestName } from './requestName.gen'; - const importRequest = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(requestName)) - ]) - ), - ts.factory.createStringLiteral(nodePath.relative(hookFolderPath, `${requestFilePath}.gen`)) - ); - const requestParamsHookKeys = getRequestParamsHookKeys(request); const requestHasRequiredParam = checkRequestHasRequiredParam(request); @@ -97,7 +89,16 @@ export const generateQueryHookFile = ({ : undefined, ts.factory.createTypeReferenceNode( ts.factory.createIdentifier('TanstackQuerySettings'), - [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(requestName))] + [ + ts.factory.createTypeQueryNode( + plugin.config.instanceVariant === 'class' + ? ts.factory.createQualifiedName( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName) + ) + ] ) ) ], @@ -164,7 +165,12 @@ export const generateQueryHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - ts.factory.createIdentifier(requestName), + plugin.config.instanceVariant === 'class' + ? ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName), undefined, [ ts.factory.createObjectLiteralExpression( @@ -208,6 +214,27 @@ export const generateQueryHookFile = ({ hookFile.add(importUseQuery); hookFile.add(importTanstackQuerySettings); - hookFile.add(importRequest); + + if (plugin.config.instanceVariant === 'function') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + hookFolderPath, + requestFilePath, + requestName + }) + ); + } + if (plugin.config.instanceVariant === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + runtimeInstancePath: plugin.config.runtimeInstancePath + }) + ); + } + hookFile.add(hookFunction); }; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts index 1eb9e90..1f037fe 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts @@ -3,9 +3,15 @@ import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; import ts from 'typescript'; +import { + capitalize, + checkRequestHasRequiredParam, + getImportInstance, + getImportRequest +} from '@/bin/plugins/helpers'; + import type { TanstackPluginConfig } from '../types'; -import { capitalize, checkRequestHasRequiredParam } from '../../helpers'; import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; interface GenerateSuspenseQueryHookParams { @@ -23,7 +29,6 @@ export const generateSuspenseQueryHookFile = ({ }: GenerateSuspenseQueryHookParams) => { const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}SuspenseQuery`; - const hookFile = plugin.createFile({ id: `${hookFolderPath}/${hookName}`, path: `${hookFolderPath}/${hookName}` @@ -68,19 +73,6 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createStringLiteral('@siberiacancode/apicraft') ); - // import type { requestName } from './requestName.gen'; - const importRequest = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(requestName)) - ]) - ), - ts.factory.createStringLiteral(nodePath.relative(hookFolderPath, `${requestFilePath}.gen`)) - ); - const optionsFunctionName = `${requestName}Options`; const requestParamsHookKeys = getRequestParamsHookKeys(request); const requestHasRequiredParam = checkRequestHasRequiredParam(request); @@ -107,7 +99,16 @@ export const generateSuspenseQueryHookFile = ({ : undefined, ts.factory.createTypeReferenceNode( ts.factory.createIdentifier('TanstackSuspenseQuerySettings'), - [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(requestName))] + [ + ts.factory.createTypeQueryNode( + plugin.config.instanceVariant === 'class' + ? ts.factory.createQualifiedName( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName) + ) + ] ) ) ], @@ -177,7 +178,12 @@ export const generateSuspenseQueryHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - ts.factory.createIdentifier(requestName), + plugin.config.instanceVariant === 'class' + ? ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier(requestName) + ) + : ts.factory.createIdentifier(requestName), undefined, [ ts.factory.createObjectLiteralExpression( @@ -264,7 +270,28 @@ export const generateSuspenseQueryHookFile = ({ hookFile.add(importUseSuspenseQuery); hookFile.add(importTanstackSuspenseQuerySettings); - hookFile.add(importRequest); + + if (plugin.config.instanceVariant === 'function') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + hookFolderPath, + requestFilePath, + requestName + }) + ); + } + if (plugin.config.instanceVariant === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + runtimeInstancePath: plugin.config.runtimeInstancePath + }) + ); + } + hookFile.add(optionsFunction); hookFile.add(hookFunction); }; diff --git a/packages/apicraft/bin/plugins/tanstack/types.d.ts b/packages/apicraft/bin/plugins/tanstack/types.d.ts index 893d2fa..0ef4488 100644 --- a/packages/apicraft/bin/plugins/tanstack/types.d.ts +++ b/packages/apicraft/bin/plugins/tanstack/types.d.ts @@ -6,9 +6,11 @@ export interface TanstackPluginConfig { exportFromIndex: boolean; generateOutput: string; groupBy?: ApicraftOption['groupBy']; + instanceVariant: 'class' | 'function'; name: 'tanstack'; nameBy?: ApicraftOption['nameBy']; output?: string; + runtimeInstancePath?: string; } export type TanstackPlugin = DefinePlugin; diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts index 5143644..e985002 100644 --- a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts @@ -4,10 +4,10 @@ import { useMutation } from "@tanstack/react-query"; import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; -import { postEcho } from "../../requests/Echo/postEcho.gen"; +import { instance } from "../../instance.gen"; -export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ +export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ mutationKey: ["postEcho"], - mutationFn: async (params) => postEcho({ ...settings?.request, ...params }), + mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), ...settings?.params }); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts index a4ba9a7..9e8214c 100644 --- a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts @@ -4,10 +4,10 @@ import { useQuery } from "@tanstack/react-query"; import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; -import { postEcho } from "../../requests/Echo/postEcho.gen"; +import { instance } from "../../instance.gen"; -export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ +export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ queryKey: ["postEcho"], - queryFn: async () => postEcho({ ...settings.request }), + queryFn: async () => instance.postEcho({ ...settings.request }), ...settings.params }); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts index 7e3c743..94a0298 100644 --- a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts @@ -4,11 +4,11 @@ import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; -import { postEcho } from "../../requests/Echo/postEcho.gen"; +import { instance } from "../../instance.gen"; -export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ +export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ queryKey: ["postEcho"], - queryFn: async () => postEcho({ ...settings.request }), + queryFn: async () => instance.postEcho({ ...settings.request }), ...settings.params }); diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts index 84aa5bb..9f00a9e 100644 --- a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts @@ -4,10 +4,10 @@ import { useMutation } from "@tanstack/react-query"; import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; -import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; +import { instance } from "../../instance.gen"; -export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ +export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ mutationKey: ["putUserByUsername", settings?.request?.path?.username], - mutationFn: async (params) => putUserByUsername({ ...settings?.request, ...params }), + mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), ...settings?.params }); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts index d49bce1..6a921b0 100644 --- a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts @@ -4,10 +4,10 @@ import { useQuery } from "@tanstack/react-query"; import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; -import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; +import { instance } from "../../instance.gen"; -export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ +export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => putUserByUsername({ ...settings.request }), + queryFn: async () => instance.putUserByUsername({ ...settings.request }), ...settings.params }); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts index 43b6b09..fb21611 100644 --- a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts @@ -4,11 +4,11 @@ import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; -import { putUserByUsername } from "../../requests/User/putUserByUsername.gen"; +import { instance } from "../../instance.gen"; -export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ +export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => putUserByUsername({ ...settings.request }), + queryFn: async () => instance.putUserByUsername({ ...settings.request }), ...settings.params }); diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts index 8542518..2f3c62c 100644 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts @@ -1,14 +1,13 @@ // This file is auto-generated by @hey-api/openapi-ts -import { useMutation } from '@tanstack/react-query'; +import { useMutation } from "@tanstack/react-query"; -import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; -import { getUsers } from '../../requests/default/getUsers.gen'; +import { instance } from "../../instance.gen"; -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => - useMutation({ - mutationKey: ['getUsers'], - mutationFn: async (params) => getUsers({ ...settings?.request, ...params }), +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["getUsers"], + mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), ...settings?.params - }); +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts index 76255fc..8841351 100644 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts @@ -4,10 +4,10 @@ import { useQuery } from "@tanstack/react-query"; import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; -import { getUsers } from "../../requests/default/getUsers.gen"; +import { instance } from "../../instance.gen"; -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ queryKey: ["getUsers"], - queryFn: async () => getUsers({ ...settings?.request }), + queryFn: async () => instance.getUsers({ ...settings?.request }), ...settings?.params }); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts index b4d6b22..851b8dc 100644 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts @@ -4,11 +4,11 @@ import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; -import { getUsers } from "../../requests/default/getUsers.gen"; +import { instance } from "../../instance.gen"; -export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ +export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ queryKey: ["getUsers"], - queryFn: async () => getUsers({ ...settings?.request }), + queryFn: async () => instance.getUsers({ ...settings?.request }), ...settings?.params }); diff --git a/packages/apicraft/generated/apiV1/instance.gen.ts b/packages/apicraft/generated/apiV1/instance.gen.ts index 7faeb07..f9081c7 100644 --- a/packages/apicraft/generated/apiV1/instance.gen.ts +++ b/packages/apicraft/generated/apiV1/instance.gen.ts @@ -10,7 +10,7 @@ import type { EchoResponse } from './types.gen'; -import axios, { AxiosInstance } from 'axios'; +import axios, { AxiosInstance, CreateAxiosDefaults } from 'axios'; export type GetUsersRequestParams = AxiosRequestParams; @@ -20,8 +20,8 @@ export type PostEchoRequestParams = AxiosRequestParams; export class ApiInstance { private instance: AxiosInstance; - constructor() { - this.instance = axios.create(); + constructor(config?: CreateAxiosDefaults) { + this.instance = axios.create(config); } getUsers({ config, query }: GetUsersRequestParams = {}) { return this.instance.request({ From d2eb2cb965d3983552b6ff01a6b9896d0ea56d5f Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 21 Feb 2026 16:07:34 +0700 Subject: [PATCH 03/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20self=20review=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/bin/generate.ts | 5 ++++- packages/apicraft/bin/helpers/index.ts | 1 - packages/apicraft/bin/plugins/axios/plugin.ts | 6 ++++- .../apicraft/bin/plugins/axiosClass/plugin.ts | 5 ++++- .../apicraft/bin/plugins/fetches/plugin.ts | 21 +++++++----------- .../axios/getAxiosRequestCallExpression.ts | 6 ++--- .../helpers/checkRequestHasRequiredParam.ts | 6 ----- .../bin/plugins/helpers/getRequestInfo.ts | 22 +++++++++---------- .../apicraft/bin/plugins/helpers/index.ts | 2 -- .../tanstack/helpers/generateQueryHookFile.ts | 21 +++++++++--------- .../helpers/generateSuspenseQueryHookFile.ts | 21 +++++++++--------- 11 files changed, 56 insertions(+), 60 deletions(-) delete mode 100644 packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts diff --git a/packages/apicraft/bin/generate.ts b/packages/apicraft/bin/generate.ts index 8130e38..d70947b 100644 --- a/packages/apicraft/bin/generate.ts +++ b/packages/apicraft/bin/generate.ts @@ -109,7 +109,10 @@ export const generate = { ...(typeof option.instance === 'object' && { runtimeInstancePath: option.instance.runtimeInstancePath }), - instanceVariant: matchInstance('axios/class') ? 'class' : 'function' + instanceVariant: + matchInstance('axios/class') || matchInstance('fetches/class') + ? 'class' + : 'function' }) ); } diff --git a/packages/apicraft/bin/helpers/index.ts b/packages/apicraft/bin/helpers/index.ts index 5cf2093..f478f5c 100644 --- a/packages/apicraft/bin/helpers/index.ts +++ b/packages/apicraft/bin/helpers/index.ts @@ -1,2 +1 @@ -export * from '../plugins/helpers/getRequestInfo'; export * from './getConfig'; diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index 125ea54..9c3d384 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -43,6 +43,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { const requestDataTypeName = `${capitalize(request.id)}Data`; const requestResponseTypeName = `${capitalize(request.id)}Response`; + // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; const importAxiosRequestParams = getImportAxiosRequestParams(); const requestFolderPath = nodePath.dirname(requestFilePath); @@ -81,6 +82,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { runtimeInstancePath: plugin.config.runtimeInstancePath }); + // type RequestParams = AxiosRequestParams; const requestParamsType = getAxiosRequestParamsType({ requestDataTypeName, requestParamsTypeName @@ -99,6 +101,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { undefined, undefined, [ + // ({ path, body, query, config }: RequestParams) getAxiosRequestParameterDeclaration({ request, requestInfo, @@ -107,11 +110,12 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + // instance.request({ method, url, data, params }) getAxiosRequestCallExpression({ request, requestInfo, requestResponseTypeName, - variant: 'function' + instanceVariant: 'function' }) ) ) diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axiosClass/plugin.ts index d58d09b..2804e1e 100644 --- a/packages/apicraft/bin/plugins/axiosClass/plugin.ts +++ b/packages/apicraft/bin/plugins/axiosClass/plugin.ts @@ -47,6 +47,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { }) ); + // ({ path, body, query, config }: RequestParams) const requestParameter = getAxiosRequestParameterDeclaration({ request, requestInfo, @@ -56,11 +57,12 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { const requestBody = ts.factory.createBlock( [ ts.factory.createReturnStatement( + // instance.request({ method, url, data, params }) getAxiosRequestCallExpression({ request, requestInfo, requestResponseTypeName, - variant: 'class' + instanceVariant: 'class' }) ) ], @@ -81,6 +83,7 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { ); }); + // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; const importAxiosRequestParams = getImportAxiosRequestParams(); // import type { RequestData, RequestResponse, ... } from './types.gen'; diff --git a/packages/apicraft/bin/plugins/fetches/plugin.ts b/packages/apicraft/bin/plugins/fetches/plugin.ts index 28f0114..4c6794b 100644 --- a/packages/apicraft/bin/plugins/fetches/plugin.ts +++ b/packages/apicraft/bin/plugins/fetches/plugin.ts @@ -6,10 +6,10 @@ import type { FetchesPlugin } from './types'; import { buildRequestParamsPath, capitalize, - checkRequestHasRequiredParam, generateRequestName, getImportInstance, - getRequestFilePaths + getRequestFilePaths, + getRequestInfo } from '../helpers'; import { addInstanceFile } from './helpers'; @@ -20,6 +20,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { if (event.type !== 'operation') return; const request = event.operation; + const requestInfo = getRequestInfo({ request }); const requestName = generateRequestName(request, plugin.config.nameBy); const requestFilePaths = getRequestFilePaths({ @@ -56,9 +57,6 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ts.factory.createStringLiteral('@siberiacancode/apicraft') ); - const requestHasResponse = Object.values(request.responses ?? {}).some( - (response) => response?.schema.$ref || response?.schema.type !== 'unknown' - ); const requestFolderPath = nodePath.dirname(requestFilePath); // import type { RequestNameData, RequestNameResponse } from 'generated/types.gen'; @@ -73,7 +71,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { undefined, ts.factory.createIdentifier(requestDataTypeName) ), - ...(requestHasResponse + ...(requestInfo.hasResponse ? [ ts.factory.createImportSpecifier( false, @@ -109,9 +107,6 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ]) ); - const requestHasPathParam = !!Object.keys(request.parameters?.path ?? {}).length; - const requestHasRequiredParam = checkRequestHasRequiredParam(request); - // --- export const requestName = ({ path, body, query, config }) => ... const requestFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], @@ -156,7 +151,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ] : []), - ...(requestHasPathParam + ...(requestInfo.hasPathParam ? [ ts.factory.createBindingElement( undefined, @@ -172,7 +167,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ts.factory.createIdentifier(requestParamsTypeName), undefined ), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createObjectLiteralExpression([], false) : undefined ) @@ -184,7 +179,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ts.factory.createIdentifier('instance'), ts.factory.createIdentifier('call') ), - requestHasResponse + requestInfo.hasResponse ? [ ts.factory.createTypeReferenceNode( ts.factory.createIdentifier(requestResponseTypeName), @@ -194,7 +189,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { : undefined, [ ts.factory.createStringLiteral(request.method.toUpperCase()), - requestHasPathParam + requestInfo.hasPathParam ? buildRequestParamsPath(request.path) : ts.factory.createStringLiteral(request.path), ts.factory.createObjectLiteralExpression( diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts index 90efb4c..630982e 100644 --- a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts +++ b/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts @@ -7,10 +7,10 @@ import type { GetRequestInfoResult } from '../getRequestInfo'; import { buildRequestParamsPath } from '../buildRequestParamsPath'; interface GetAxiosRequestCallExpressionParams { + instanceVariant: 'class' | 'function'; request: IR.OperationObject; requestInfo: GetRequestInfoResult; requestResponseTypeName: string; - variant: 'class' | 'function'; } // instance.request({ method, url, data, params }) @@ -18,10 +18,10 @@ export const getAxiosRequestCallExpression = ({ request, requestInfo, requestResponseTypeName, - variant + instanceVariant }: GetAxiosRequestCallExpressionParams) => ts.factory.createCallExpression( - variant === 'class' + instanceVariant === 'class' ? ts.factory.createPropertyAccessExpression( ts.factory.createPropertyAccessExpression( ts.factory.createThis(), diff --git a/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts b/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts deleted file mode 100644 index c9110c8..0000000 --- a/packages/apicraft/bin/plugins/helpers/checkRequestHasRequiredParam.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { IR } from '@hey-api/openapi-ts'; - -export const checkRequestHasRequiredParam = (request: IR.OperationObject) => - Object.values(request.parameters?.query ?? {}).some((queryParam) => queryParam.required) || - Object.values(request.parameters?.path ?? {}).some((pathParam) => pathParam.required) || - !!request.body?.required; diff --git a/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts b/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts index 11e53ec..049e627 100644 --- a/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts +++ b/packages/apicraft/bin/plugins/helpers/getRequestInfo.ts @@ -10,15 +10,13 @@ export interface GetRequestInfoResult { hasResponse: boolean; } -export const getRequestInfo = ({ request }: GetRequestInfoParams): GetRequestInfoResult => { - return { - hasResponse: Object.values(request.responses ?? {}).some( - (response) => response?.schema.$ref || response?.schema.type !== 'unknown' - ), - hasPathParam: !!Object.keys(request.parameters?.path ?? {}).length, - hasRequiredParam: - Object.values(request.parameters?.query ?? {}).some((queryParam) => queryParam.required) || - Object.values(request.parameters?.path ?? {}).some((pathParam) => pathParam.required) || - !!request.body?.required - }; -}; +export const getRequestInfo = ({ request }: GetRequestInfoParams): GetRequestInfoResult => ({ + hasResponse: Object.values(request.responses ?? {}).some( + (response) => response?.schema.$ref || response?.schema.type !== 'unknown' + ), + hasPathParam: !!Object.keys(request.parameters?.path ?? {}).length, + hasRequiredParam: + Object.values(request.parameters?.query ?? {}).some((queryParam) => queryParam.required) || + Object.values(request.parameters?.path ?? {}).some((pathParam) => pathParam.required) || + !!request.body?.required +}); diff --git a/packages/apicraft/bin/plugins/helpers/index.ts b/packages/apicraft/bin/plugins/helpers/index.ts index 72313b3..db49048 100644 --- a/packages/apicraft/bin/plugins/helpers/index.ts +++ b/packages/apicraft/bin/plugins/helpers/index.ts @@ -1,10 +1,8 @@ export * from './axios'; export * from './buildRequestParamsPath'; export * from './capitalize'; -export * from './checkRequestHasRequiredParam'; export * from './generatePathRequestName'; export * from './generateRequestName'; export * from './getRequestFilePaths'; export * from './getRequestInfo'; -export * from './getRequestInfo'; export * from './imports'; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts index bc4778c..dcaecc8 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts @@ -5,9 +5,9 @@ import ts from 'typescript'; import { capitalize, - checkRequestHasRequiredParam, getImportInstance, - getImportRequest + getImportRequest, + getRequestInfo } from '@/bin/plugins/helpers'; import type { TanstackPluginConfig } from '../types'; @@ -27,6 +27,8 @@ export const generateQueryHookFile = ({ requestName, requestFilePath }: GenerateQueryHookParams) => { + const requestInfo = getRequestInfo({ request }); + const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}Query`; const hookFile = plugin.createFile({ @@ -65,7 +67,6 @@ export const generateQueryHookFile = ({ ); const requestParamsHookKeys = getRequestParamsHookKeys(request); - const requestHasRequiredParam = checkRequestHasRequiredParam(request); // const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery const hookFunction = ts.factory.createVariableStatement( @@ -84,7 +85,7 @@ export const generateQueryHookFile = ({ undefined, undefined, ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, ts.factory.createTypeReferenceNode( @@ -118,12 +119,12 @@ export const generateQueryHookFile = ({ ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') ), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('path') @@ -137,12 +138,12 @@ export const generateQueryHookFile = ({ ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') ), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('query') @@ -178,7 +179,7 @@ export const generateQueryHookFile = ({ ts.factory.createSpreadAssignment( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') @@ -195,7 +196,7 @@ export const generateQueryHookFile = ({ ts.factory.createSpreadAssignment( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('params') diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts index 1f037fe..c9f836c 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts @@ -5,9 +5,9 @@ import ts from 'typescript'; import { capitalize, - checkRequestHasRequiredParam, getImportInstance, - getImportRequest + getImportRequest, + getRequestInfo } from '@/bin/plugins/helpers'; import type { TanstackPluginConfig } from '../types'; @@ -27,6 +27,8 @@ export const generateSuspenseQueryHookFile = ({ requestName, requestFilePath }: GenerateSuspenseQueryHookParams) => { + const requestInfo = getRequestInfo({ request }); + const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}SuspenseQuery`; const hookFile = plugin.createFile({ @@ -75,7 +77,6 @@ export const generateSuspenseQueryHookFile = ({ const optionsFunctionName = `${requestName}Options`; const requestParamsHookKeys = getRequestParamsHookKeys(request); - const requestHasRequiredParam = checkRequestHasRequiredParam(request); // const requestNameOptions = queryOptions({...}) const optionsFunction = ts.factory.createVariableStatement( @@ -94,7 +95,7 @@ export const generateSuspenseQueryHookFile = ({ undefined, undefined, ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, ts.factory.createTypeReferenceNode( @@ -131,12 +132,12 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') ), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('path') @@ -150,12 +151,12 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') ), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('query') @@ -191,7 +192,7 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createSpreadAssignment( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('request') @@ -208,7 +209,7 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createSpreadAssignment( ts.factory.createPropertyAccessChain( ts.factory.createIdentifier('settings'), - !requestHasRequiredParam + !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, ts.factory.createIdentifier('params') From 439a65f771cb921ad8dc6245d3a0a6464f50e95d Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 21 Feb 2026 16:53:59 +0700 Subject: [PATCH 04/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20support=20runtime=20instance=20for=20axios=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/apicraft.config.ts | 2 +- packages/apicraft/bin/generate.ts | 26 ++---- .../plugins/axios/helpers/addInstanceFile.ts | 8 +- packages/apicraft/bin/plugins/axios/plugin.ts | 10 +- .../helpers/getImportRuntimeInstance.ts | 29 ++++++ .../bin/plugins/axiosClass/helpers/index.ts | 1 + .../apicraft/bin/plugins/axiosClass/plugin.ts | 91 ++++++++++++------- .../bin/plugins/axiosClass/types.d.ts | 1 + .../apicraft/bin/plugins/fetches/plugin.ts | 10 +- .../plugins/helpers/axios/getImportAxios.ts | 9 ++ .../bin/plugins/helpers/axios/index.ts | 1 + .../helpers/imports/getImportInstance.ts | 4 +- .../helpers/imports/getImportRequest.ts | 8 +- .../helpers/generateMutationHookFile.ts | 12 ++- .../tanstack/helpers/generateQueryHookFile.ts | 12 ++- .../helpers/generateSuspenseQueryHookFile.ts | 12 ++- .../apicraft/bin/plugins/tanstack/types.d.ts | 1 - .../hooks/default/useGetUsersMutation.gen.ts | 15 +-- .../hooks/default/useGetUsersQuery.gen.ts | 13 +-- .../apicraft/generated/apiV1/instance.gen.ts | 8 +- packages/apicraft/src/test-runtime.ts | 3 + 21 files changed, 184 insertions(+), 92 deletions(-) create mode 100644 packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts create mode 100644 packages/apicraft/bin/plugins/axiosClass/helpers/index.ts create mode 100644 packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts create mode 100644 packages/apicraft/src/test-runtime.ts diff --git a/packages/apicraft/apicraft.config.ts b/packages/apicraft/apicraft.config.ts index c9058bb..bd4b9a8 100644 --- a/packages/apicraft/apicraft.config.ts +++ b/packages/apicraft/apicraft.config.ts @@ -8,7 +8,7 @@ const apicraftConfig = apicraft([ { input: 'example-apiV2.yaml', output: 'generated/apiV1', - instance: 'axios/class', + instance: { name: 'axios/class', runtimeInstancePath: 'src/test-runtime' }, nameBy: 'path', groupBy: 'tag', plugins: ['tanstack'] diff --git a/packages/apicraft/bin/generate.ts b/packages/apicraft/bin/generate.ts index d70947b..f1c90da 100644 --- a/packages/apicraft/bin/generate.ts +++ b/packages/apicraft/bin/generate.ts @@ -52,14 +52,16 @@ export const generate = { option.instance === name || (typeof option.instance === 'object' && option.instance.name === name); + const generateOutput = + typeof option.output === 'string' ? option.output : option.output.path; + const runtimeInstancePath = + typeof option.instance === 'object' ? option.instance.runtimeInstancePath : undefined; + if (matchInstance('axios')) { plugins.push( defineAxiosPlugin({ - generateOutput: - typeof option.output === 'string' ? option.output : option.output.path, - ...(typeof option.instance === 'object' && { - runtimeInstancePath: option.instance.runtimeInstancePath - }), + generateOutput, + runtimeInstancePath, exportFromIndex: true, nameBy: option.nameBy, groupBy: option.groupBy @@ -70,8 +72,8 @@ export const generate = { if (matchInstance('axios/class')) { plugins.push( defineAxiosClassPlugin({ - generateOutput: - typeof option.output === 'string' ? option.output : option.output.path, + generateOutput, + runtimeInstancePath, exportFromIndex: true, nameBy: option.nameBy, groupBy: option.groupBy @@ -79,16 +81,11 @@ export const generate = { ); } - const generateOutput = - typeof option.output === 'string' ? option.output : option.output.path; - if (matchInstance('fetches')) { plugins.push( defineFetchesPlugin({ generateOutput, - ...(typeof option.instance === 'object' && { - runtimeInstancePath: option.instance.runtimeInstancePath - }), + runtimeInstancePath, exportFromIndex: true, nameBy: option.nameBy, groupBy: option.groupBy @@ -106,9 +103,6 @@ export const generate = { exportFromIndex: true, nameBy: option.nameBy, groupBy: option.groupBy, - ...(typeof option.instance === 'object' && { - runtimeInstancePath: option.instance.runtimeInstancePath - }), instanceVariant: matchInstance('axios/class') || matchInstance('fetches/class') ? 'class' diff --git a/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts b/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts index aad6683..c1bd67a 100644 --- a/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts +++ b/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts @@ -3,6 +3,8 @@ import type { DefinePlugin } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; import ts from 'typescript'; +import { getImportAxios } from '@/bin/plugins/helpers'; + export const addInstanceFile = (plugin: DefinePlugin['Instance']) => { const instanceFile = plugin.createFile({ id: 'axiosInstance', @@ -10,11 +12,7 @@ export const addInstanceFile = (plugin: DefinePlugin['Instance']) => { }); // import axios from 'axios'; - const importAxios = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause(false, ts.factory.createIdentifier('axios'), undefined), - ts.factory.createStringLiteral('axios') - ); + const importAxios = getImportAxios(); // export const instance = axios.create(); const createInstance = ts.factory.createVariableStatement( diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index 9c3d384..3f56f87 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -45,7 +45,9 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; const importAxiosRequestParams = getImportAxiosRequestParams(); - const requestFolderPath = nodePath.dirname(requestFilePath); + const requestFolderPath = nodePath.dirname( + `${plugin.config.generateOutput}/${requestFilePath}` + ); // import type { RequestData, RequestResponse } from 'generated/types.gen'; const importTypes = ts.factory.createImportDeclaration( @@ -71,7 +73,10 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { ]) ), ts.factory.createStringLiteral( - nodePath.relative(requestFolderPath, nodePath.normalize('types.gen')) + nodePath.relative( + requestFolderPath, + nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) + ) ) ); @@ -79,6 +84,7 @@ export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { const importInstance = getImportInstance({ folderPath: requestFolderPath, output: plugin.output, + generateOutput: plugin.config.generateOutput, runtimeInstancePath: plugin.config.runtimeInstancePath }); diff --git a/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts b/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts new file mode 100644 index 0000000..c83f331 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts @@ -0,0 +1,29 @@ +import nodePath from 'node:path'; +import ts from 'typescript'; + +interface GetImportRuntimeInstanceParams { + classFolderPath: string; + runtimeInstancePath: string; +} + +// import { instance as runtimeInstance } from runtimeInstancePath; +export const getImportRuntimeInstance = ({ + classFolderPath, + runtimeInstancePath +}: GetImportRuntimeInstanceParams) => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + false, + ts.factory.createIdentifier('instance'), + ts.factory.createIdentifier('runtimeInstance') + ) + ]) + ), + ts.factory.createStringLiteral(nodePath.relative(classFolderPath, runtimeInstancePath)), + undefined + ); diff --git a/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts b/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts new file mode 100644 index 0000000..e1abe50 --- /dev/null +++ b/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts @@ -0,0 +1 @@ +export * from './getImportRuntimeInstance'; diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axiosClass/plugin.ts index 2804e1e..8f5a5c6 100644 --- a/packages/apicraft/bin/plugins/axiosClass/plugin.ts +++ b/packages/apicraft/bin/plugins/axiosClass/plugin.ts @@ -9,14 +9,17 @@ import { getAxiosRequestCallExpression, getAxiosRequestParameterDeclaration, getAxiosRequestParamsType, + getImportAxios, getImportAxiosRequestParams, getRequestInfo } from '../helpers'; +import { getImportRuntimeInstance } from './helpers'; const CLASS_NAME = 'ApiInstance'; export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { const classFilePath = nodePath.normalize(`${plugin.output}/instance`); + const classFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${classFilePath}`); const classFile = plugin.createFile({ id: 'axiosInstance', path: classFilePath @@ -105,26 +108,31 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { ts.factory.createStringLiteral('./types.gen') ); - // import axios, { AxiosInstance, CreateAxiosDefaults } from 'axios'; - const importAxios = ts.factory.createImportDeclaration( + // import type { AxiosInstance, CreateAxiosDefaults } from 'axios'; + const importAxiosTypes = ts.factory.createImportDeclaration( undefined, ts.factory.createImportClause( - false, - ts.factory.createIdentifier('axios'), + true, + undefined, ts.factory.createNamedImports([ ts.factory.createImportSpecifier( false, undefined, ts.factory.createIdentifier('AxiosInstance') ), - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier('CreateAxiosDefaults') - ) + ...(!plugin.config.runtimeInstancePath + ? [ + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier('CreateAxiosDefaults') + ) + ] + : []) ]) ), - ts.factory.createStringLiteral('axios') + ts.factory.createStringLiteral('axios'), + undefined ); // private instance: AxiosInstance; @@ -139,19 +147,21 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { // constructor(config?: CreateAxiosDefaults) { this.instance = axios.create(config); } const constructorDeclaration = ts.factory.createConstructorDeclaration( undefined, - [ - ts.factory.createParameterDeclaration( - undefined, - undefined, - ts.factory.createIdentifier('config'), - ts.factory.createToken(ts.SyntaxKind.QuestionToken), - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier('CreateAxiosDefaults'), - undefined - ), - undefined - ) - ], + !plugin.config.runtimeInstancePath + ? [ + ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier('config'), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier('CreateAxiosDefaults'), + undefined + ), + undefined + ) + ] + : [], ts.factory.createBlock( [ ts.factory.createExpressionStatement( @@ -161,14 +171,16 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { ts.factory.createIdentifier('instance') ), ts.factory.createToken(ts.SyntaxKind.EqualsToken), - ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier('axios'), - ts.factory.createIdentifier('create') - ), - undefined, - [ts.factory.createIdentifier('config')] - ) + plugin.config.runtimeInstancePath + ? ts.factory.createIdentifier('runtimeInstance') + : ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('axios'), + ts.factory.createIdentifier('create') + ), + undefined, + !plugin.config.runtimeInstancePath ? [ts.factory.createIdentifier('config')] : [] + ) ) ) ], @@ -203,7 +215,22 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { classFile.add(importAxiosRequestParams); classFile.add(importTypes); - classFile.add(importAxios); + classFile.add(importAxiosTypes); + + if (!plugin.config.runtimeInstancePath) { + // import axios from 'axios'; + classFile.add(getImportAxios()); + } + if (plugin.config.runtimeInstancePath) { + // import { instance as runtimeInstance } from runtimeInstancePath; + classFile.add( + getImportRuntimeInstance({ + classFolderPath, + runtimeInstancePath: plugin.config.runtimeInstancePath + }) + ); + } + typeStatements.forEach((alias) => classFile.add(alias)); classFile.add(classDeclaration); classFile.add(classInstance); diff --git a/packages/apicraft/bin/plugins/axiosClass/types.d.ts b/packages/apicraft/bin/plugins/axiosClass/types.d.ts index 7afeb48..0b48e02 100644 --- a/packages/apicraft/bin/plugins/axiosClass/types.d.ts +++ b/packages/apicraft/bin/plugins/axiosClass/types.d.ts @@ -9,6 +9,7 @@ export interface AxiosClassPluginConfig { name: 'axiosClass'; nameBy?: ApicraftOption['nameBy']; output?: string; + runtimeInstancePath?: string; } export type AxiosClassPlugin = DefinePlugin; diff --git a/packages/apicraft/bin/plugins/fetches/plugin.ts b/packages/apicraft/bin/plugins/fetches/plugin.ts index 4c6794b..9b7ed52 100644 --- a/packages/apicraft/bin/plugins/fetches/plugin.ts +++ b/packages/apicraft/bin/plugins/fetches/plugin.ts @@ -57,7 +57,9 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ts.factory.createStringLiteral('@siberiacancode/apicraft') ); - const requestFolderPath = nodePath.dirname(requestFilePath); + const requestFolderPath = nodePath.dirname( + `${plugin.config.generateOutput}/${requestFilePath}` + ); // import type { RequestNameData, RequestNameResponse } from 'generated/types.gen'; const importTypes = ts.factory.createImportDeclaration( @@ -83,7 +85,10 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { ]) ), ts.factory.createStringLiteral( - nodePath.relative(requestFolderPath, nodePath.normalize('types.gen')) + nodePath.relative( + requestFolderPath, + nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) + ) ) ); @@ -91,6 +96,7 @@ export const handler: FetchesPlugin['Handler'] = ({ plugin }) => { const importInstance = getImportInstance({ folderPath: requestFolderPath, output: plugin.output, + generateOutput: plugin.config.generateOutput, runtimeInstancePath: plugin.config.runtimeInstancePath }); diff --git a/packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts b/packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts new file mode 100644 index 0000000..792f55a --- /dev/null +++ b/packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts @@ -0,0 +1,9 @@ +import ts from 'typescript'; + +// import axios from 'axios'; +export const getImportAxios = () => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause(false, ts.factory.createIdentifier('axios'), undefined), + ts.factory.createStringLiteral('axios') + ); diff --git a/packages/apicraft/bin/plugins/helpers/axios/index.ts b/packages/apicraft/bin/plugins/helpers/axios/index.ts index f3ec096..d0f5546 100644 --- a/packages/apicraft/bin/plugins/helpers/axios/index.ts +++ b/packages/apicraft/bin/plugins/helpers/axios/index.ts @@ -1,4 +1,5 @@ export * from './getAxiosRequestCallExpression'; export * from './getAxiosRequestParameterDeclaration'; export * from './getAxiosRequestParamsType'; +export * from './getImportAxios'; export * from './getImportAxiosRequestParams'; diff --git a/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts index bfd2046..86cff65 100644 --- a/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts +++ b/packages/apicraft/bin/plugins/helpers/imports/getImportInstance.ts @@ -3,6 +3,7 @@ import ts from 'typescript'; interface GetImportInstanceParams { folderPath: string; + generateOutput: string; output: string; runtimeInstancePath?: string; } @@ -10,6 +11,7 @@ interface GetImportInstanceParams { // import { instance } from '../../instance.gen'; export const getImportInstance = ({ output, + generateOutput, runtimeInstancePath, folderPath }: GetImportInstanceParams) => @@ -25,7 +27,7 @@ export const getImportInstance = ({ ts.factory.createStringLiteral( nodePath.relative( folderPath, - runtimeInstancePath ?? nodePath.normalize(`${output}/instance.gen`) + runtimeInstancePath ?? nodePath.normalize(`${generateOutput}/${output}/instance.gen`) ) ) ); diff --git a/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts index e6a2a5d..e1b6f98 100644 --- a/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts +++ b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts @@ -2,6 +2,7 @@ import nodePath from 'node:path'; import ts from 'typescript'; interface GetImportRequestParams { + generateOutput: string; hookFolderPath: string; requestFilePath: string; requestName: string; @@ -11,7 +12,8 @@ interface GetImportRequestParams { export const getImportRequest = ({ hookFolderPath, requestFilePath, - requestName + requestName, + generateOutput }: GetImportRequestParams) => ts.factory.createImportDeclaration( undefined, @@ -22,5 +24,7 @@ export const getImportRequest = ({ ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(requestName)) ]) ), - ts.factory.createStringLiteral(nodePath.relative(hookFolderPath, `${requestFilePath}.gen`)) + ts.factory.createStringLiteral( + nodePath.relative(hookFolderPath, `${generateOutput}/${requestFilePath}.gen`) + ) ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts index 7c92078..a44e45a 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts @@ -22,11 +22,12 @@ export const generateMutationHookFile = ({ requestName, requestFilePath }: GenerateMutationHookFileParams) => { - const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}Mutation`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); const hookFile = plugin.createFile({ - id: `${hookFolderPath}/${hookName}`, - path: `${hookFolderPath}/${hookName}` + id: hookName, + path: hookFilePath }); // import { useMutation } from '@tanstack/react-query'; @@ -214,7 +215,8 @@ export const generateMutationHookFile = ({ getImportRequest({ hookFolderPath, requestFilePath, - requestName + requestName, + generateOutput: plugin.config.generateOutput }) ); } @@ -224,7 +226,7 @@ export const generateMutationHookFile = ({ getImportInstance({ output: plugin.output, folderPath: hookFolderPath, - runtimeInstancePath: plugin.config.runtimeInstancePath + generateOutput: plugin.config.generateOutput }) ); } diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts index dcaecc8..7e26d9d 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts @@ -29,11 +29,12 @@ export const generateQueryHookFile = ({ }: GenerateQueryHookParams) => { const requestInfo = getRequestInfo({ request }); - const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}Query`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); const hookFile = plugin.createFile({ - id: `${hookFolderPath}/${hookName}`, - path: `${hookFolderPath}/${hookName}` + id: hookName, + path: hookFilePath }); // import { useQuery } from '@tanstack/react-query'; @@ -222,7 +223,8 @@ export const generateQueryHookFile = ({ getImportRequest({ hookFolderPath, requestFilePath, - requestName + requestName, + generateOutput: plugin.config.generateOutput }) ); } @@ -232,7 +234,7 @@ export const generateQueryHookFile = ({ getImportInstance({ output: plugin.output, folderPath: hookFolderPath, - runtimeInstancePath: plugin.config.runtimeInstancePath + generateOutput: plugin.config.generateOutput }) ); } diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts index c9f836c..5e5303c 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts @@ -29,11 +29,12 @@ export const generateSuspenseQueryHookFile = ({ }: GenerateSuspenseQueryHookParams) => { const requestInfo = getRequestInfo({ request }); - const hookFolderPath = nodePath.dirname(requestFilePath).replace('requests', 'hooks'); const hookName = `use${capitalize(requestName)}SuspenseQuery`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); const hookFile = plugin.createFile({ - id: `${hookFolderPath}/${hookName}`, - path: `${hookFolderPath}/${hookName}` + id: hookName, + path: hookFilePath }); // import { queryOptions, useSuspenseQuery } from '@tanstack/react-query'; @@ -278,7 +279,8 @@ export const generateSuspenseQueryHookFile = ({ getImportRequest({ hookFolderPath, requestFilePath, - requestName + requestName, + generateOutput: plugin.config.generateOutput }) ); } @@ -288,7 +290,7 @@ export const generateSuspenseQueryHookFile = ({ getImportInstance({ output: plugin.output, folderPath: hookFolderPath, - runtimeInstancePath: plugin.config.runtimeInstancePath + generateOutput: plugin.config.generateOutput }) ); } diff --git a/packages/apicraft/bin/plugins/tanstack/types.d.ts b/packages/apicraft/bin/plugins/tanstack/types.d.ts index 0ef4488..c23b383 100644 --- a/packages/apicraft/bin/plugins/tanstack/types.d.ts +++ b/packages/apicraft/bin/plugins/tanstack/types.d.ts @@ -10,7 +10,6 @@ export interface TanstackPluginConfig { name: 'tanstack'; nameBy?: ApicraftOption['nameBy']; output?: string; - runtimeInstancePath?: string; } export type TanstackPlugin = DefinePlugin; diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts index 2f3c62c..058b8fd 100644 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts @@ -1,13 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts -import { useMutation } from "@tanstack/react-query"; +import { useMutation } from '@tanstack/react-query'; -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; +import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; -import { instance } from "../../instance.gen"; +import { instance } from '../../instance.gen'; -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["getUsers"], +export const useGetUsersMutation = ( + settings?: TanstackMutationSettings +) => + useMutation({ + mutationKey: ['getUsers'], mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), ...settings?.params -}); \ No newline at end of file + }); diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts index 8841351..84a1356 100644 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts +++ b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts @@ -1,13 +1,14 @@ // This file is auto-generated by @hey-api/openapi-ts -import { useQuery } from "@tanstack/react-query"; +import { useQuery } from '@tanstack/react-query'; -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; +import type { TanstackQuerySettings } from '@siberiacancode/apicraft'; -import { instance } from "../../instance.gen"; +import { instance } from '../../instance.gen'; -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ - queryKey: ["getUsers"], +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => + useQuery({ + queryKey: ['getUsers'], queryFn: async () => instance.getUsers({ ...settings?.request }), ...settings?.params -}); \ No newline at end of file + }); diff --git a/packages/apicraft/generated/apiV1/instance.gen.ts b/packages/apicraft/generated/apiV1/instance.gen.ts index f9081c7..5696b65 100644 --- a/packages/apicraft/generated/apiV1/instance.gen.ts +++ b/packages/apicraft/generated/apiV1/instance.gen.ts @@ -10,7 +10,9 @@ import type { EchoResponse } from './types.gen'; -import axios, { AxiosInstance, CreateAxiosDefaults } from 'axios'; +import type { AxiosInstance } from 'axios'; + +import { instance as runtimeInstance } from '../../src/test-runtime'; export type GetUsersRequestParams = AxiosRequestParams; @@ -20,8 +22,8 @@ export type PostEchoRequestParams = AxiosRequestParams; export class ApiInstance { private instance: AxiosInstance; - constructor(config?: CreateAxiosDefaults) { - this.instance = axios.create(config); + constructor() { + this.instance = runtimeInstance; } getUsers({ config, query }: GetUsersRequestParams = {}) { return this.instance.request({ diff --git a/packages/apicraft/src/test-runtime.ts b/packages/apicraft/src/test-runtime.ts new file mode 100644 index 0000000..896817e --- /dev/null +++ b/packages/apicraft/src/test-runtime.ts @@ -0,0 +1,3 @@ +import axios from 'axios'; + +export const instance = axios.create({}); From 037015e8f87bddfc944ef303bc5421dc775a318f Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 21 Feb 2026 17:02:18 +0700 Subject: [PATCH 05/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20add=20generation=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/apicraft.config.ts | 10 +- .../helpers/getImportRuntimeInstance.ts | 6 +- .../apicraft/bin/plugins/axiosClass/plugin.ts | 10 +- .../helpers/imports/getImportRequest.ts | 6 +- .../helpers/generateMutationHookFile.ts | 2 +- .../tanstack/helpers/generateQueryHookFile.ts | 2 +- .../helpers/generateSuspenseQueryHookFile.ts | 2 +- .../hooks/default/useGetUsersMutation.gen.ts | 16 --- .../hooks/default/useGetUsersQuery.gen.ts | 14 --- .../hooks/Echo/usePostEchoMutation.gen.ts | 0 .../hooks/Echo/usePostEchoQuery.gen.ts | 0 .../Echo/usePostEchoSuspenseQuery.gen.ts | 0 .../User/usePutUserByUsernameMutation.gen.ts | 0 .../User/usePutUserByUsernameQuery.gen.ts | 0 .../usePutUserByUsernameSuspenseQuery.gen.ts | 0 .../hooks/default/useGetUsersMutation.gen.ts | 13 ++ .../hooks/default/useGetUsersQuery.gen.ts | 13 ++ .../default/useGetUsersSuspenseQuery.gen.ts | 0 .../index.ts | 0 .../instance.gen.ts | 0 .../types.gen.ts | 0 .../hooks/Echo/usePostEchoMutation.gen.ts | 13 ++ .../hooks/Echo/usePostEchoQuery.gen.ts | 13 ++ .../Echo/usePostEchoSuspenseQuery.gen.ts | 15 +++ .../User/usePutUserByUsernameMutation.gen.ts | 13 ++ .../User/usePutUserByUsernameQuery.gen.ts | 13 ++ .../usePutUserByUsernameSuspenseQuery.gen.ts | 15 +++ .../hooks/default/useGetUsersMutation.gen.ts | 13 ++ .../hooks/default/useGetUsersQuery.gen.ts | 13 ++ .../default/useGetUsersSuspenseQuery.gen.ts | 15 +++ .../apicraft/generated/apiV2-class/index.ts | 12 ++ .../generated/apiV2-class/instance.gen.ts | 55 +++++++++ .../generated/apiV2-class/types.gen.ts | 115 ++++++++++++++++++ 33 files changed, 354 insertions(+), 45 deletions(-) delete mode 100644 packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/Echo/usePostEchoMutation.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/Echo/usePostEchoQuery.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/Echo/usePostEchoSuspenseQuery.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/User/usePutUserByUsernameMutation.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/User/usePutUserByUsernameQuery.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts (100%) create mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/hooks/default/useGetUsersSuspenseQuery.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/index.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/instance.gen.ts (100%) rename packages/apicraft/generated/{apiV1 => apiV2-class-runtime-instance}/types.gen.ts (100%) create mode 100644 packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/index.ts create mode 100644 packages/apicraft/generated/apiV2-class/instance.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/types.gen.ts diff --git a/packages/apicraft/apicraft.config.ts b/packages/apicraft/apicraft.config.ts index bd4b9a8..328ec43 100644 --- a/packages/apicraft/apicraft.config.ts +++ b/packages/apicraft/apicraft.config.ts @@ -7,7 +7,15 @@ import { apicraft } from './dist/esm/index.mjs'; const apicraftConfig = apicraft([ { input: 'example-apiV2.yaml', - output: 'generated/apiV1', + output: 'generated/apiV2-class', + instance: 'axios/class', + nameBy: 'path', + groupBy: 'tag', + plugins: ['tanstack'] + }, + { + input: 'example-apiV2.yaml', + output: 'generated/apiV2-class-runtime-instance', instance: { name: 'axios/class', runtimeInstancePath: 'src/test-runtime' }, nameBy: 'path', groupBy: 'tag', diff --git a/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts b/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts index c83f331..09ca4be 100644 --- a/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts +++ b/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts @@ -2,13 +2,13 @@ import nodePath from 'node:path'; import ts from 'typescript'; interface GetImportRuntimeInstanceParams { - classFolderPath: string; + folderPath: string; runtimeInstancePath: string; } // import { instance as runtimeInstance } from runtimeInstancePath; export const getImportRuntimeInstance = ({ - classFolderPath, + folderPath, runtimeInstancePath }: GetImportRuntimeInstanceParams) => ts.factory.createImportDeclaration( @@ -24,6 +24,6 @@ export const getImportRuntimeInstance = ({ ) ]) ), - ts.factory.createStringLiteral(nodePath.relative(classFolderPath, runtimeInstancePath)), + ts.factory.createStringLiteral(nodePath.relative(folderPath, runtimeInstancePath)), undefined ); diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axiosClass/plugin.ts index 8f5a5c6..c0b0528 100644 --- a/packages/apicraft/bin/plugins/axiosClass/plugin.ts +++ b/packages/apicraft/bin/plugins/axiosClass/plugin.ts @@ -217,19 +217,19 @@ export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { classFile.add(importTypes); classFile.add(importAxiosTypes); - if (!plugin.config.runtimeInstancePath) { - // import axios from 'axios'; - classFile.add(getImportAxios()); - } if (plugin.config.runtimeInstancePath) { // import { instance as runtimeInstance } from runtimeInstancePath; classFile.add( getImportRuntimeInstance({ - classFolderPath, + folderPath: classFolderPath, runtimeInstancePath: plugin.config.runtimeInstancePath }) ); } + if (!plugin.config.runtimeInstancePath) { + // import axios from 'axios'; + classFile.add(getImportAxios()); + } typeStatements.forEach((alias) => classFile.add(alias)); classFile.add(classDeclaration); diff --git a/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts index e1b6f98..24b8962 100644 --- a/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts +++ b/packages/apicraft/bin/plugins/helpers/imports/getImportRequest.ts @@ -2,15 +2,15 @@ import nodePath from 'node:path'; import ts from 'typescript'; interface GetImportRequestParams { + folderPath: string; generateOutput: string; - hookFolderPath: string; requestFilePath: string; requestName: string; } // import type { requestName } from './requestName.gen'; export const getImportRequest = ({ - hookFolderPath, + folderPath, requestFilePath, requestName, generateOutput @@ -25,6 +25,6 @@ export const getImportRequest = ({ ]) ), ts.factory.createStringLiteral( - nodePath.relative(hookFolderPath, `${generateOutput}/${requestFilePath}.gen`) + nodePath.relative(folderPath, `${generateOutput}/${requestFilePath}.gen`) ) ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts index a44e45a..3563e0d 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts @@ -213,7 +213,7 @@ export const generateMutationHookFile = ({ // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ - hookFolderPath, + folderPath: hookFolderPath, requestFilePath, requestName, generateOutput: plugin.config.generateOutput diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts index 7e26d9d..d30a8c5 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts @@ -221,7 +221,7 @@ export const generateQueryHookFile = ({ // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ - hookFolderPath, + folderPath: hookFolderPath, requestFilePath, requestName, generateOutput: plugin.config.generateOutput diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts index 5e5303c..825c810 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts @@ -277,7 +277,7 @@ export const generateSuspenseQueryHookFile = ({ // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ - hookFolderPath, + folderPath: hookFolderPath, requestFilePath, requestName, generateOutput: plugin.config.generateOutput diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts deleted file mode 100644 index 058b8fd..0000000 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersMutation.gen.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from '@tanstack/react-query'; - -import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; - -import { instance } from '../../instance.gen'; - -export const useGetUsersMutation = ( - settings?: TanstackMutationSettings -) => - useMutation({ - mutationKey: ['getUsers'], - mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), - ...settings?.params - }); diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts deleted file mode 100644 index 84a1356..0000000 --- a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersQuery.gen.ts +++ /dev/null @@ -1,14 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from '@tanstack/react-query'; - -import type { TanstackQuerySettings } from '@siberiacancode/apicraft'; - -import { instance } from '../../instance.gen'; - -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => - useQuery({ - queryKey: ['getUsers'], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params - }); diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoMutation.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoQuery.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts diff --git a/packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/Echo/usePostEchoSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameMutation.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameQuery.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts diff --git a/packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts new file mode 100644 index 0000000..2f3c62c --- /dev/null +++ b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["getUsers"], + mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts new file mode 100644 index 0000000..8841351 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ + queryKey: ["getUsers"], + queryFn: async () => instance.getUsers({ ...settings?.request }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersSuspenseQuery.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/hooks/default/useGetUsersSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersSuspenseQuery.gen.ts diff --git a/packages/apicraft/generated/apiV1/index.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts similarity index 100% rename from packages/apicraft/generated/apiV1/index.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/index.ts diff --git a/packages/apicraft/generated/apiV1/instance.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/instance.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts diff --git a/packages/apicraft/generated/apiV1/types.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts similarity index 100% rename from packages/apicraft/generated/apiV1/types.gen.ts rename to packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts new file mode 100644 index 0000000..e985002 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["postEcho"], + mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts new file mode 100644 index 0000000..9e8214c --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["postEcho"], + queryFn: async () => instance.postEcho({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts new file mode 100644 index 0000000..94a0298 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["postEcho"], + queryFn: async () => instance.postEcho({ ...settings.request }), + ...settings.params +}); + +export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts new file mode 100644 index 0000000..9f00a9e --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["putUserByUsername", settings?.request?.path?.username], + mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts new file mode 100644 index 0000000..6a921b0 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["putUserByUsername", settings.request.path?.username], + queryFn: async () => instance.putUserByUsername({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts new file mode 100644 index 0000000..fb21611 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["putUserByUsername", settings.request.path?.username], + queryFn: async () => instance.putUserByUsername({ ...settings.request }), + ...settings.params +}); + +export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts new file mode 100644 index 0000000..2f3c62c --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useMutation } from "@tanstack/react-query"; + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["getUsers"], + mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts new file mode 100644 index 0000000..8841351 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ + queryKey: ["getUsers"], + queryFn: async () => instance.getUsers({ ...settings?.request }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts new file mode 100644 index 0000000..851b8dc --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "../../instance.gen"; + +export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["getUsers"], + queryFn: async () => instance.getUsers({ ...settings?.request }), + ...settings?.params +}); + +export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/index.ts b/packages/apicraft/generated/apiV2-class/index.ts new file mode 100644 index 0000000..75b106f --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/index.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './types.gen'; +export * from './hooks/default/useGetUsersQuery.gen'; +export * from './hooks/default/useGetUsersSuspenseQuery.gen'; +export * from './hooks/default/useGetUsersMutation.gen'; +export * from './hooks/User/usePutUserByUsernameQuery.gen'; +export * from './hooks/User/usePutUserByUsernameSuspenseQuery.gen'; +export * from './hooks/User/usePutUserByUsernameMutation.gen'; +export * from './hooks/Echo/usePostEchoQuery.gen'; +export * from './hooks/Echo/usePostEchoSuspenseQuery.gen'; +export * from './hooks/Echo/usePostEchoMutation.gen'; +export * from './instance.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/instance.gen.ts b/packages/apicraft/generated/apiV2-class/instance.gen.ts new file mode 100644 index 0000000..e284481 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/instance.gen.ts @@ -0,0 +1,55 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosRequestParams } from '@siberiacancode/apicraft'; + +import type { + GetUserByNameData, + GetUserByNameResponse, + UpdateUserData, + EchoData, + EchoResponse +} from './types.gen'; + +import type { AxiosInstance, CreateAxiosDefaults } from 'axios'; + +import axios from 'axios'; + +export type GetUsersRequestParams = AxiosRequestParams; + +export type PutUserByUsernameRequestParams = AxiosRequestParams; + +export type PostEchoRequestParams = AxiosRequestParams; + +export class ApiInstance { + private instance: AxiosInstance; + constructor(config?: CreateAxiosDefaults) { + this.instance = axios.create(config); + } + getUsers({ config, query }: GetUsersRequestParams = {}) { + return this.instance.request({ + method: 'GET', + url: '/users', + params: query, + ...config + }); + } + putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { + return this.instance.request({ + method: 'PUT', + url: `/users/${path.username}`, + data: body, + params: query, + ...config + }); + } + postEcho({ config, body }: PostEchoRequestParams) { + return this.instance.request({ + method: 'POST', + url: '/echo', + data: body, + ...config + }); + } +} + +export const instance = new ApiInstance(); diff --git a/packages/apicraft/generated/apiV2-class/types.gen.ts b/packages/apicraft/generated/apiV2-class/types.gen.ts new file mode 100644 index 0000000..bfb2c6e --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/types.gen.ts @@ -0,0 +1,115 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * User email address + */ +export type Email = string; + +export type User = { + /** + * User supplied username + */ + username?: string; + /** + * User first name + */ + firstName?: string; + /** + * User last name + */ + lastName?: string; + email?: Email; +}; + +export type GetUserByNameData = { + body?: never; + path?: never; + query?: { + /** + * Filter users without email + */ + with_email?: boolean; + }; + url: '/users'; +}; + +export type GetUserByNameErrors = { + /** + * Forbidden + */ + 403: unknown; + /** + * User not found + */ + 404: unknown; +}; + +export type GetUserByNameResponses = { + /** + * Success + */ + 200: User; +}; + +export type GetUserByNameResponse = GetUserByNameResponses[keyof GetUserByNameResponses]; + +export type UpdateUserData = { + /** + * Updated user object + */ + body: User; + path: { + /** + * The name that needs to be updated + */ + username: string; + }; + query?: { + /** + * Pretty print response + */ + pretty_print?: boolean; + }; + url: '/users/{username}'; +}; + +export type UpdateUserErrors = { + /** + * Invalid user supplied + */ + 400: unknown; + /** + * User not found + */ + 404: unknown; +}; + +export type UpdateUserResponses = { + /** + * OK + */ + 200: unknown; +}; + +export type EchoData = { + /** + * Echo payload + */ + body: string; + path?: never; + query?: never; + url: '/echo'; +}; + +export type EchoResponses = { + /** + * OK + */ + 200: string; +}; + +export type EchoResponse = EchoResponses[keyof EchoResponses]; + +export type ClientOptions = { + baseUrl: 'http://example.com/api/v1' | 'https://example.com/api/v1' | (string & {}); +}; \ No newline at end of file From a51a2f6359633983cfa959bb978cd942acacd97d Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Tue, 24 Feb 2026 00:00:07 +0700 Subject: [PATCH 06/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20rework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/bin/generate.ts | 19 +-- .../{axiosClass => axios/class}/plugin.ts | 11 +- .../bin/plugins/axios/composed/plugin.ts | 143 ++++++++++++++++++ packages/apicraft/bin/plugins/axios/config.ts | 2 +- .../helpers}/getAxiosRequestCallExpression.ts | 0 .../getAxiosRequestParameterDeclaration.ts | 0 .../helpers}/getAxiosRequestParamsType.ts | 0 .../axios => axios/helpers}/getImportAxios.ts | 0 .../helpers}/getImportAxiosRequestParams.ts | 0 .../helpers/getImportRuntimeInstance.ts | 0 .../bin/plugins/axios/helpers/index.ts | 8 +- packages/apicraft/bin/plugins/axios/plugin.ts | 141 +---------------- .../apicraft/bin/plugins/axiosClass/config.ts | 18 --- .../bin/plugins/axiosClass/helpers/index.ts | 1 - .../apicraft/bin/plugins/axiosClass/index.ts | 2 - .../bin/plugins/axiosClass/types.d.ts | 15 -- .../bin/plugins/helpers/axios/index.ts | 5 - .../apicraft/bin/plugins/helpers/index.ts | 1 - .../apicraft/bin/plugins/tanstack/config.ts | 3 +- .../helpers/generateMutationHookFile.ts | 22 +-- .../tanstack/helpers/generateQueryHookFile.ts | 22 +-- .../helpers/generateSuspenseQueryHookFile.ts | 22 +-- .../apicraft/bin/plugins/tanstack/types.d.ts | 1 - packages/apicraft/bin/schemas/index.ts | 4 +- 24 files changed, 197 insertions(+), 243 deletions(-) rename packages/apicraft/bin/plugins/{axiosClass => axios/class}/plugin.ts (96%) create mode 100644 packages/apicraft/bin/plugins/axios/composed/plugin.ts rename packages/apicraft/bin/plugins/{helpers/axios => axios/helpers}/getAxiosRequestCallExpression.ts (100%) rename packages/apicraft/bin/plugins/{helpers/axios => axios/helpers}/getAxiosRequestParameterDeclaration.ts (100%) rename packages/apicraft/bin/plugins/{helpers/axios => axios/helpers}/getAxiosRequestParamsType.ts (100%) rename packages/apicraft/bin/plugins/{helpers/axios => axios/helpers}/getImportAxios.ts (100%) rename packages/apicraft/bin/plugins/{helpers/axios => axios/helpers}/getImportAxiosRequestParams.ts (100%) rename packages/apicraft/bin/plugins/{axiosClass => axios}/helpers/getImportRuntimeInstance.ts (100%) delete mode 100644 packages/apicraft/bin/plugins/axiosClass/config.ts delete mode 100644 packages/apicraft/bin/plugins/axiosClass/helpers/index.ts delete mode 100644 packages/apicraft/bin/plugins/axiosClass/index.ts delete mode 100644 packages/apicraft/bin/plugins/axiosClass/types.d.ts delete mode 100644 packages/apicraft/bin/plugins/helpers/axios/index.ts diff --git a/packages/apicraft/bin/generate.ts b/packages/apicraft/bin/generate.ts index f1c90da..8e86ff0 100644 --- a/packages/apicraft/bin/generate.ts +++ b/packages/apicraft/bin/generate.ts @@ -9,7 +9,6 @@ import { getConfig } from '@/bin/helpers'; import type { ApicraftOption, GenerateApicraftOption, InstanceName } from './schemas'; import { defineAxiosPlugin } from './plugins/axios'; -import { defineAxiosClassPlugin } from './plugins/axiosClass'; import { defineFetchesPlugin } from './plugins/fetches'; import { defineTanstackPlugin } from './plugins/tanstack'; import { apicraftConfigSchema, apicraftOptionSchema } from './schemas'; @@ -69,18 +68,6 @@ export const generate = { ); } - if (matchInstance('axios/class')) { - plugins.push( - defineAxiosClassPlugin({ - generateOutput, - runtimeInstancePath, - exportFromIndex: true, - nameBy: option.nameBy, - groupBy: option.groupBy - }) - ); - } - if (matchInstance('fetches')) { plugins.push( defineFetchesPlugin({ @@ -102,11 +89,7 @@ export const generate = { generateOutput, exportFromIndex: true, nameBy: option.nameBy, - groupBy: option.groupBy, - instanceVariant: - matchInstance('axios/class') || matchInstance('fetches/class') - ? 'class' - : 'function' + groupBy: option.groupBy }) ); } diff --git a/packages/apicraft/bin/plugins/axiosClass/plugin.ts b/packages/apicraft/bin/plugins/axios/class/plugin.ts similarity index 96% rename from packages/apicraft/bin/plugins/axiosClass/plugin.ts rename to packages/apicraft/bin/plugins/axios/class/plugin.ts index c0b0528..e816e0c 100644 --- a/packages/apicraft/bin/plugins/axiosClass/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/class/plugin.ts @@ -1,23 +1,22 @@ import * as nodePath from 'node:path'; import ts from 'typescript'; -import type { AxiosClassPlugin } from './types'; +import { capitalize, generateRequestName, getRequestInfo } from '@/bin/plugins/helpers'; + +import type { AxiosPlugin } from '../types'; import { - capitalize, - generateRequestName, getAxiosRequestCallExpression, getAxiosRequestParameterDeclaration, getAxiosRequestParamsType, getImportAxios, getImportAxiosRequestParams, - getRequestInfo + getImportRuntimeInstance } from '../helpers'; -import { getImportRuntimeInstance } from './helpers'; const CLASS_NAME = 'ApiInstance'; -export const handler: AxiosClassPlugin['Handler'] = ({ plugin }) => { +export const classHandler: AxiosPlugin['Handler'] = ({ plugin }) => { const classFilePath = nodePath.normalize(`${plugin.output}/instance`); const classFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${classFilePath}`); const classFile = plugin.createFile({ diff --git a/packages/apicraft/bin/plugins/axios/composed/plugin.ts b/packages/apicraft/bin/plugins/axios/composed/plugin.ts new file mode 100644 index 0000000..6626198 --- /dev/null +++ b/packages/apicraft/bin/plugins/axios/composed/plugin.ts @@ -0,0 +1,143 @@ +import * as nodePath from 'node:path'; +import ts from 'typescript'; + +import { + capitalize, + generateRequestName, + getImportInstance, + getRequestFilePaths, + getRequestInfo +} from '@/bin/plugins/helpers'; + +import type { AxiosPlugin } from '../types'; + +import { + addInstanceFile, + getAxiosRequestCallExpression, + getAxiosRequestParameterDeclaration, + getAxiosRequestParamsType, + getImportAxiosRequestParams +} from '../helpers'; + +export const composedHandler: AxiosPlugin['Handler'] = ({ plugin }) => { + if (!plugin.config.runtimeInstancePath) addInstanceFile(plugin); + + plugin.forEach('operation', (event) => { + if (event.type !== 'operation') return; + + const request = event.operation; + const requestInfo = getRequestInfo({ request }); + const requestName = generateRequestName(request, plugin.config.nameBy); + + const requestFilePaths = getRequestFilePaths({ + groupBy: plugin.config.groupBy, + output: plugin.output, + requestName, + request + }); + + requestFilePaths.forEach((requestFilePath) => { + const requestFile = plugin.createFile({ + id: requestFilePath, + path: requestFilePath + }); + + const requestParamsTypeName = `${capitalize(requestName)}RequestParams`; + const requestDataTypeName = `${capitalize(request.id)}Data`; + const requestResponseTypeName = `${capitalize(request.id)}Response`; + + // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; + const importAxiosRequestParams = getImportAxiosRequestParams(); + const requestFolderPath = nodePath.dirname( + `${plugin.config.generateOutput}/${requestFilePath}` + ); + + // import type { RequestData, RequestResponse } from 'generated/types.gen'; + const importTypes = ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + true, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier(requestDataTypeName) + ), + ...(requestInfo.hasResponse + ? [ + ts.factory.createImportSpecifier( + false, + undefined, + ts.factory.createIdentifier(requestResponseTypeName) + ) + ] + : []) + ]) + ), + ts.factory.createStringLiteral( + nodePath.relative( + requestFolderPath, + nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) + ) + ) + ); + + // import { instance } from "../../instance.gen"; + const importInstance = getImportInstance({ + folderPath: requestFolderPath, + output: plugin.output, + generateOutput: plugin.config.generateOutput, + runtimeInstancePath: plugin.config.runtimeInstancePath + }); + + // type RequestParams = AxiosRequestParams; + const requestParamsType = getAxiosRequestParamsType({ + requestDataTypeName, + requestParamsTypeName + }); + + // --- export const request = ({ path, body, query, config }) => ... + const requestFunction = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(requestName), + undefined, + undefined, + ts.factory.createArrowFunction( + undefined, + undefined, + [ + // ({ path, body, query, config }: RequestParams) + getAxiosRequestParameterDeclaration({ + request, + requestInfo, + requestParamsTypeName + }) + ], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + // instance.request({ method, url, data, params }) + getAxiosRequestCallExpression({ + request, + requestInfo, + requestResponseTypeName, + instanceVariant: 'function' + }) + ) + ) + ], + ts.NodeFlags.Const + ) + ); + + requestFile.add(importAxiosRequestParams); + requestFile.add(importTypes); + requestFile.add(importInstance); + requestFile.add(requestParamsType); + requestFile.add(requestFunction); + }); + }); +}; diff --git a/packages/apicraft/bin/plugins/axios/config.ts b/packages/apicraft/bin/plugins/axios/config.ts index 53bcd37..881db74 100644 --- a/packages/apicraft/bin/plugins/axios/config.ts +++ b/packages/apicraft/bin/plugins/axios/config.ts @@ -2,7 +2,7 @@ import { definePluginConfig } from '@hey-api/openapi-ts'; import type { AxiosPlugin } from './types'; -import { handler } from './plugin'; +import { handler } from './composed/plugin'; export const defaultConfig: AxiosPlugin['Config'] = { config: { diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts b/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts similarity index 100% rename from packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestCallExpression.ts rename to packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts b/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestParameterDeclaration.ts similarity index 100% rename from packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParameterDeclaration.ts rename to packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestParameterDeclaration.ts diff --git a/packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts b/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestParamsType.ts similarity index 100% rename from packages/apicraft/bin/plugins/helpers/axios/getAxiosRequestParamsType.ts rename to packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestParamsType.ts diff --git a/packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts b/packages/apicraft/bin/plugins/axios/helpers/getImportAxios.ts similarity index 100% rename from packages/apicraft/bin/plugins/helpers/axios/getImportAxios.ts rename to packages/apicraft/bin/plugins/axios/helpers/getImportAxios.ts diff --git a/packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts b/packages/apicraft/bin/plugins/axios/helpers/getImportAxiosRequestParams.ts similarity index 100% rename from packages/apicraft/bin/plugins/helpers/axios/getImportAxiosRequestParams.ts rename to packages/apicraft/bin/plugins/axios/helpers/getImportAxiosRequestParams.ts diff --git a/packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts b/packages/apicraft/bin/plugins/axios/helpers/getImportRuntimeInstance.ts similarity index 100% rename from packages/apicraft/bin/plugins/axiosClass/helpers/getImportRuntimeInstance.ts rename to packages/apicraft/bin/plugins/axios/helpers/getImportRuntimeInstance.ts diff --git a/packages/apicraft/bin/plugins/axios/helpers/index.ts b/packages/apicraft/bin/plugins/axios/helpers/index.ts index 146069b..1a04759 100644 --- a/packages/apicraft/bin/plugins/axios/helpers/index.ts +++ b/packages/apicraft/bin/plugins/axios/helpers/index.ts @@ -1 +1,7 @@ -export { addInstanceFile } from './addInstanceFile'; +export * from './addInstanceFile'; +export * from './getAxiosRequestCallExpression'; +export * from './getAxiosRequestParameterDeclaration'; +export * from './getAxiosRequestParamsType'; +export * from './getImportAxios'; +export * from './getImportAxiosRequestParams'; +export * from './getImportRuntimeInstance'; diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index 3f56f87..68f76ab 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -1,140 +1,7 @@ -import * as nodePath from 'node:path'; -import ts from 'typescript'; - import type { AxiosPlugin } from './types'; -import { - capitalize, - generateRequestName, - getAxiosRequestCallExpression, - getAxiosRequestParameterDeclaration, - getAxiosRequestParamsType, - getImportAxiosRequestParams, - getImportInstance, - getRequestFilePaths, - getRequestInfo -} from '../helpers'; -import { addInstanceFile } from './helpers'; - -export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { - if (!plugin.config.runtimeInstancePath) addInstanceFile(plugin); - - plugin.forEach('operation', (event) => { - if (event.type !== 'operation') return; - - const request = event.operation; - const requestInfo = getRequestInfo({ request }); - const requestName = generateRequestName(request, plugin.config.nameBy); - - const requestFilePaths = getRequestFilePaths({ - groupBy: plugin.config.groupBy, - output: plugin.output, - requestName, - request - }); - - requestFilePaths.forEach((requestFilePath) => { - const requestFile = plugin.createFile({ - id: requestFilePath, - path: requestFilePath - }); - - const requestParamsTypeName = `${capitalize(requestName)}RequestParams`; - const requestDataTypeName = `${capitalize(request.id)}Data`; - const requestResponseTypeName = `${capitalize(request.id)}Response`; - - // import type { AxiosRequestParams } from '@siberiacancode/apicraft'; - const importAxiosRequestParams = getImportAxiosRequestParams(); - const requestFolderPath = nodePath.dirname( - `${plugin.config.generateOutput}/${requestFilePath}` - ); - - // import type { RequestData, RequestResponse } from 'generated/types.gen'; - const importTypes = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - true, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier(requestDataTypeName) - ), - ...(requestInfo.hasResponse - ? [ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier(requestResponseTypeName) - ) - ] - : []) - ]) - ), - ts.factory.createStringLiteral( - nodePath.relative( - requestFolderPath, - nodePath.normalize(`${plugin.config.generateOutput}/types.gen`) - ) - ) - ); - - // import { instance } from "../../instance.gen"; - const importInstance = getImportInstance({ - folderPath: requestFolderPath, - output: plugin.output, - generateOutput: plugin.config.generateOutput, - runtimeInstancePath: plugin.config.runtimeInstancePath - }); - - // type RequestParams = AxiosRequestParams; - const requestParamsType = getAxiosRequestParamsType({ - requestDataTypeName, - requestParamsTypeName - }); - - // --- export const request = ({ path, body, query, config }) => ... - const requestFunction = ts.factory.createVariableStatement( - [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], - ts.factory.createVariableDeclarationList( - [ - ts.factory.createVariableDeclaration( - ts.factory.createIdentifier(requestName), - undefined, - undefined, - ts.factory.createArrowFunction( - undefined, - undefined, - [ - // ({ path, body, query, config }: RequestParams) - getAxiosRequestParameterDeclaration({ - request, - requestInfo, - requestParamsTypeName - }) - ], - undefined, - ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - // instance.request({ method, url, data, params }) - getAxiosRequestCallExpression({ - request, - requestInfo, - requestResponseTypeName, - instanceVariant: 'function' - }) - ) - ) - ], - ts.NodeFlags.Const - ) - ); +import { classHandler } from './class/plugin'; +import { composedHandler } from './composed/plugin'; - requestFile.add(importAxiosRequestParams); - requestFile.add(importTypes); - requestFile.add(importInstance); - requestFile.add(requestParamsType); - requestFile.add(requestFunction); - }); - }); -}; +export const handler: AxiosPlugin['Handler'] = ({ plugin }) => + plugin.config.groupBy === 'class' ? classHandler({ plugin }) : composedHandler({ plugin }); diff --git a/packages/apicraft/bin/plugins/axiosClass/config.ts b/packages/apicraft/bin/plugins/axiosClass/config.ts deleted file mode 100644 index f1595e5..0000000 --- a/packages/apicraft/bin/plugins/axiosClass/config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { definePluginConfig } from '@hey-api/openapi-ts'; - -import type { AxiosClassPlugin } from './types'; - -import { handler } from './plugin'; - -export const defaultConfig: AxiosClassPlugin['Config'] = { - config: { - generateOutput: '', - exportFromIndex: true - }, - dependencies: ['@hey-api/typescript'], - handler, - name: 'axiosClass', - output: '.' -}; - -export const defineAxiosClassPlugin = definePluginConfig(defaultConfig); diff --git a/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts b/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts deleted file mode 100644 index e1abe50..0000000 --- a/packages/apicraft/bin/plugins/axiosClass/helpers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './getImportRuntimeInstance'; diff --git a/packages/apicraft/bin/plugins/axiosClass/index.ts b/packages/apicraft/bin/plugins/axiosClass/index.ts deleted file mode 100644 index f03d024..0000000 --- a/packages/apicraft/bin/plugins/axiosClass/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { defineAxiosClassPlugin } from './config'; -export type { AxiosClassPlugin } from './types'; diff --git a/packages/apicraft/bin/plugins/axiosClass/types.d.ts b/packages/apicraft/bin/plugins/axiosClass/types.d.ts deleted file mode 100644 index 0b48e02..0000000 --- a/packages/apicraft/bin/plugins/axiosClass/types.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { DefinePlugin } from '@hey-api/openapi-ts'; - -import type { ApicraftOption } from '@/bin/schemas'; - -export interface AxiosClassPluginConfig { - exportFromIndex: boolean; - generateOutput: string; - groupBy?: ApicraftOption['groupBy']; - name: 'axiosClass'; - nameBy?: ApicraftOption['nameBy']; - output?: string; - runtimeInstancePath?: string; -} - -export type AxiosClassPlugin = DefinePlugin; diff --git a/packages/apicraft/bin/plugins/helpers/axios/index.ts b/packages/apicraft/bin/plugins/helpers/axios/index.ts deleted file mode 100644 index d0f5546..0000000 --- a/packages/apicraft/bin/plugins/helpers/axios/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './getAxiosRequestCallExpression'; -export * from './getAxiosRequestParameterDeclaration'; -export * from './getAxiosRequestParamsType'; -export * from './getImportAxios'; -export * from './getImportAxiosRequestParams'; diff --git a/packages/apicraft/bin/plugins/helpers/index.ts b/packages/apicraft/bin/plugins/helpers/index.ts index db49048..6b4137c 100644 --- a/packages/apicraft/bin/plugins/helpers/index.ts +++ b/packages/apicraft/bin/plugins/helpers/index.ts @@ -1,4 +1,3 @@ -export * from './axios'; export * from './buildRequestParamsPath'; export * from './capitalize'; export * from './generatePathRequestName'; diff --git a/packages/apicraft/bin/plugins/tanstack/config.ts b/packages/apicraft/bin/plugins/tanstack/config.ts index 94b8836..b08ea2c 100644 --- a/packages/apicraft/bin/plugins/tanstack/config.ts +++ b/packages/apicraft/bin/plugins/tanstack/config.ts @@ -7,8 +7,7 @@ import { handler } from './plugin'; export const defaultConfig: TanstackPlugin['Config'] = { config: { generateOutput: '', - exportFromIndex: true, - instanceVariant: 'function' + exportFromIndex: true }, dependencies: ['@hey-api/typescript'], handler, diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts index 3563e0d..cb1cdd2 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts @@ -88,7 +88,7 @@ export const generateMutationHookFile = ({ ts.factory.createIdentifier('TanstackMutationSettings'), [ ts.factory.createTypeQueryNode( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createQualifiedName( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -160,7 +160,7 @@ export const generateMutationHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createPropertyAccessExpression( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -209,23 +209,23 @@ export const generateMutationHookFile = ({ hookFile.add(importUseMutation); hookFile.add(importTanstackMutationSettings); - if (plugin.config.instanceVariant === 'function') { - // import type { requestName } from './requestName.gen'; + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; hookFile.add( - getImportRequest({ + getImportInstance({ + output: plugin.output, folderPath: hookFolderPath, - requestFilePath, - requestName, generateOutput: plugin.config.generateOutput }) ); } - if (plugin.config.instanceVariant === 'class') { - // import { instance } from '../../instance.gen'; + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; hookFile.add( - getImportInstance({ - output: plugin.output, + getImportRequest({ folderPath: hookFolderPath, + requestFilePath, + requestName, generateOutput: plugin.config.generateOutput }) ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts index d30a8c5..4f33655 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts @@ -93,7 +93,7 @@ export const generateQueryHookFile = ({ ts.factory.createIdentifier('TanstackQuerySettings'), [ ts.factory.createTypeQueryNode( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createQualifiedName( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -167,7 +167,7 @@ export const generateQueryHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createPropertyAccessExpression( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -217,23 +217,23 @@ export const generateQueryHookFile = ({ hookFile.add(importUseQuery); hookFile.add(importTanstackQuerySettings); - if (plugin.config.instanceVariant === 'function') { - // import type { requestName } from './requestName.gen'; + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; hookFile.add( - getImportRequest({ + getImportInstance({ + output: plugin.output, folderPath: hookFolderPath, - requestFilePath, - requestName, generateOutput: plugin.config.generateOutput }) ); } - if (plugin.config.instanceVariant === 'class') { - // import { instance } from '../../instance.gen'; + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; hookFile.add( - getImportInstance({ - output: plugin.output, + getImportRequest({ folderPath: hookFolderPath, + requestFilePath, + requestName, generateOutput: plugin.config.generateOutput }) ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts index 825c810..a8f7e66 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts @@ -103,7 +103,7 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createIdentifier('TanstackSuspenseQuerySettings'), [ ts.factory.createTypeQueryNode( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createQualifiedName( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -180,7 +180,7 @@ export const generateSuspenseQueryHookFile = ({ undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression( - plugin.config.instanceVariant === 'class' + plugin.config.groupBy === 'class' ? ts.factory.createPropertyAccessExpression( ts.factory.createIdentifier('instance'), ts.factory.createIdentifier(requestName) @@ -273,23 +273,23 @@ export const generateSuspenseQueryHookFile = ({ hookFile.add(importUseSuspenseQuery); hookFile.add(importTanstackSuspenseQuerySettings); - if (plugin.config.instanceVariant === 'function') { - // import type { requestName } from './requestName.gen'; + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; hookFile.add( - getImportRequest({ + getImportInstance({ + output: plugin.output, folderPath: hookFolderPath, - requestFilePath, - requestName, generateOutput: plugin.config.generateOutput }) ); } - if (plugin.config.instanceVariant === 'class') { - // import { instance } from '../../instance.gen'; + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; hookFile.add( - getImportInstance({ - output: plugin.output, + getImportRequest({ folderPath: hookFolderPath, + requestFilePath, + requestName, generateOutput: plugin.config.generateOutput }) ); diff --git a/packages/apicraft/bin/plugins/tanstack/types.d.ts b/packages/apicraft/bin/plugins/tanstack/types.d.ts index c23b383..893d2fa 100644 --- a/packages/apicraft/bin/plugins/tanstack/types.d.ts +++ b/packages/apicraft/bin/plugins/tanstack/types.d.ts @@ -6,7 +6,6 @@ export interface TanstackPluginConfig { exportFromIndex: boolean; generateOutput: string; groupBy?: ApicraftOption['groupBy']; - instanceVariant: 'class' | 'function'; name: 'tanstack'; nameBy?: ApicraftOption['nameBy']; output?: string; diff --git a/packages/apicraft/bin/schemas/index.ts b/packages/apicraft/bin/schemas/index.ts index 65e6fa9..93b073e 100644 --- a/packages/apicraft/bin/schemas/index.ts +++ b/packages/apicraft/bin/schemas/index.ts @@ -1,6 +1,6 @@ import * as z from 'zod'; -const instanceNameSchema = z.enum(['fetches', 'axios', 'fetches/class', 'axios/class']); +const instanceNameSchema = z.enum(['fetches', 'axios']); const instanceSchema = z.object({ name: instanceNameSchema, runtimeInstancePath: z.string().optional() @@ -123,7 +123,7 @@ export const apicraftOptionSchema = z .optional(), instance: z.union([instanceNameSchema, instanceSchema]).optional(), nameBy: z.enum(['path', 'operationId']).default('operationId').optional(), - groupBy: z.enum(['path', 'tag']).default('tag').optional(), + groupBy: z.enum(['paths', 'tags', 'class']).default('tags').optional(), plugins: z .array(pluginNameSchema.or(z.object({ name: pluginNameSchema }).passthrough())) .optional() From da9fed10b9bfadc10a2ace1c7af446ffc51b6244 Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Wed, 25 Feb 2026 12:08:44 +0700 Subject: [PATCH 07/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20rework=20plugins=20for=202=20cases:=20class=20and=20composed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/apicraft.config.ts | 8 +- packages/apicraft/bin/plugins/axios/config.ts | 2 +- .../plugins/axios/helpers/addInstanceFile.ts | 2 +- .../helpers/getAxiosRequestCallExpression.ts | 4 +- .../plugins/helpers/getRequestFilePaths.ts | 8 +- .../bin/plugins/tanstack/class/plugin.ts | 71 ++++++++ .../helpers/generateMutationHookFile.ts | 61 +++++++ .../composed/helpers/generateQueryHookFile.ts | 66 ++++++++ .../helpers/generateSuspenseQueryHookFile.ts | 72 ++++++++ .../tanstack/composed/helpers/index.ts | 3 + .../bin/plugins/tanstack/composed/plugin.ts | 30 ++++ .../tanstack/helpers/getApicraftTypeImport.ts | 17 ++ ...MutationHookFile.ts => getMutationHook.ts} | 131 +++------------ ...nerateQueryHookFile.ts => getQueryHook.ts} | 143 ++++------------ .../helpers/getRequestParamsHookKeys.ts | 10 -- ...eryHookFile.ts => getSuspenseQueryHook.ts} | 155 ++++-------------- .../tanstack/helpers/getTanstackImport.ts | 17 ++ .../bin/plugins/tanstack/helpers/index.ts | 8 +- .../apicraft/bin/plugins/tanstack/plugin.ts | 28 +--- .../apiV2-class-runtime-instance/hooks.gen.ts | 85 ++++++++++ .../hooks/Echo/usePostEchoMutation.gen.ts | 13 -- .../hooks/Echo/usePostEchoQuery.gen.ts | 13 -- .../Echo/usePostEchoSuspenseQuery.gen.ts | 15 -- .../User/usePutUserByUsernameMutation.gen.ts | 13 -- .../User/usePutUserByUsernameQuery.gen.ts | 13 -- .../usePutUserByUsernameSuspenseQuery.gen.ts | 15 -- .../hooks/default/useGetUsersMutation.gen.ts | 13 -- .../hooks/default/useGetUsersQuery.gen.ts | 13 -- .../apiV2-class-runtime-instance/index.ts | 10 +- .../instance.gen.ts | 74 ++++----- .../hooks/Echo/usePostEchoMutation.gen.ts | 13 -- .../hooks/Echo/usePostEchoQuery.gen.ts | 13 -- .../User/usePutUserByUsernameMutation.gen.ts | 13 -- .../User/usePutUserByUsernameQuery.gen.ts | 13 -- .../hooks/default/useGetUsersMutation.gen.ts | 13 -- .../hooks/default/useGetUsersQuery.gen.ts | 13 -- .../default/useGetUsersSuspenseQuery.gen.ts | 15 -- .../hooks/echo/usePostEchoMutation.gen.ts | 15 ++ .../hooks/echo/usePostEchoQuery.gen.ts | 15 ++ .../usePostEchoSuspenseQuery.gen.ts | 12 +- .../hooks/users/useGetUsersMutation.gen.ts | 15 ++ .../hooks/users/useGetUsersQuery.gen.ts | 15 ++ .../users}/useGetUsersSuspenseQuery.gen.ts | 12 +- .../usePutUserByUsernameMutation.gen.ts | 15 ++ .../usePutUserByUsernameQuery.gen.ts | 15 ++ .../usePutUserByUsernameSuspenseQuery.gen.ts | 12 +- .../apicraft/generated/apiV2-class/index.ts | 23 +-- .../generated/apiV2-class/instance.gen.ts | 54 +----- .../apiV2-class/requests/echo/post.gen.ts | 16 ++ .../apiV2-class/requests/users/get.gen.ts | 16 ++ .../requests/users/{username}/put.gen.ts | 17 ++ 51 files changed, 740 insertions(+), 718 deletions(-) create mode 100644 packages/apicraft/bin/plugins/tanstack/class/plugin.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/composed/helpers/index.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/composed/plugin.ts create mode 100644 packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts rename packages/apicraft/bin/plugins/tanstack/helpers/{generateMutationHookFile.ts => getMutationHook.ts} (54%) rename packages/apicraft/bin/plugins/tanstack/helpers/{generateQueryHookFile.ts => getQueryHook.ts} (51%) delete mode 100644 packages/apicraft/bin/plugins/tanstack/helpers/getRequestParamsHookKeys.ts rename packages/apicraft/bin/plugins/tanstack/helpers/{generateSuspenseQueryHookFile.ts => getSuspenseQueryHook.ts} (57%) create mode 100644 packages/apicraft/bin/plugins/tanstack/helpers/getTanstackImport.ts create mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts rename packages/apicraft/generated/apiV2-class/hooks/{Echo => echo}/usePostEchoSuspenseQuery.gen.ts (56%) create mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts rename packages/apicraft/generated/{apiV2-class-runtime-instance/hooks/default => apiV2-class/hooks/users}/useGetUsersSuspenseQuery.gen.ts (56%) create mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts rename packages/apicraft/generated/apiV2-class/hooks/{User => users/{username}}/usePutUserByUsernameSuspenseQuery.gen.ts (53%) create mode 100644 packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts create mode 100644 packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts diff --git a/packages/apicraft/apicraft.config.ts b/packages/apicraft/apicraft.config.ts index 328ec43..2b58ac3 100644 --- a/packages/apicraft/apicraft.config.ts +++ b/packages/apicraft/apicraft.config.ts @@ -8,17 +8,17 @@ const apicraftConfig = apicraft([ { input: 'example-apiV2.yaml', output: 'generated/apiV2-class', - instance: 'axios/class', + instance: 'axios', nameBy: 'path', - groupBy: 'tag', + groupBy: 'paths', plugins: ['tanstack'] }, { input: 'example-apiV2.yaml', output: 'generated/apiV2-class-runtime-instance', - instance: { name: 'axios/class', runtimeInstancePath: 'src/test-runtime' }, + instance: { name: 'axios', runtimeInstancePath: 'src/test-runtime' }, nameBy: 'path', - groupBy: 'tag', + groupBy: 'class', plugins: ['tanstack'] } ]); diff --git a/packages/apicraft/bin/plugins/axios/config.ts b/packages/apicraft/bin/plugins/axios/config.ts index 881db74..53bcd37 100644 --- a/packages/apicraft/bin/plugins/axios/config.ts +++ b/packages/apicraft/bin/plugins/axios/config.ts @@ -2,7 +2,7 @@ import { definePluginConfig } from '@hey-api/openapi-ts'; import type { AxiosPlugin } from './types'; -import { handler } from './composed/plugin'; +import { handler } from './plugin'; export const defaultConfig: AxiosPlugin['Config'] = { config: { diff --git a/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts b/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts index c1bd67a..6139f97 100644 --- a/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts +++ b/packages/apicraft/bin/plugins/axios/helpers/addInstanceFile.ts @@ -3,7 +3,7 @@ import type { DefinePlugin } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; import ts from 'typescript'; -import { getImportAxios } from '@/bin/plugins/helpers'; +import { getImportAxios } from './getImportAxios'; export const addInstanceFile = (plugin: DefinePlugin['Instance']) => { const instanceFile = plugin.createFile({ diff --git a/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts b/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts index 630982e..0ce01d5 100644 --- a/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts +++ b/packages/apicraft/bin/plugins/axios/helpers/getAxiosRequestCallExpression.ts @@ -2,9 +2,9 @@ import type { IR } from '@hey-api/openapi-ts'; import ts from 'typescript'; -import type { GetRequestInfoResult } from '../getRequestInfo'; +import type { GetRequestInfoResult } from '@/bin/plugins/helpers'; -import { buildRequestParamsPath } from '../buildRequestParamsPath'; +import { buildRequestParamsPath } from '@/bin/plugins/helpers'; interface GetAxiosRequestCallExpressionParams { instanceVariant: 'class' | 'function'; diff --git a/packages/apicraft/bin/plugins/helpers/getRequestFilePaths.ts b/packages/apicraft/bin/plugins/helpers/getRequestFilePaths.ts index f4cd316..cee391c 100644 --- a/packages/apicraft/bin/plugins/helpers/getRequestFilePaths.ts +++ b/packages/apicraft/bin/plugins/helpers/getRequestFilePaths.ts @@ -17,17 +17,21 @@ export const getRequestFilePaths = ({ groupBy, output }: GetRequestFilePathsParams) => { - if (groupBy === 'tag') { + if (groupBy === 'tags') { const tags = request.tags ?? ['default']; return tags.map((tag) => nodePath.normalize(`${output}/requests/${tag}/${requestName}`)); } - if (groupBy === 'path') { + if (groupBy === 'paths') { return [ nodePath.normalize(`${output}/requests/${request.path}/${request.method.toLowerCase()}`) ]; } + if (groupBy === 'class') { + return [nodePath.normalize(`${output}/instance.gen`)]; + } + throw new Error(`Unsupported groupBy option ${groupBy}`); }; diff --git a/packages/apicraft/bin/plugins/tanstack/class/plugin.ts b/packages/apicraft/bin/plugins/tanstack/class/plugin.ts new file mode 100644 index 0000000..216ed54 --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/class/plugin.ts @@ -0,0 +1,71 @@ +import type ts from 'typescript'; + +import { capitalize, generateRequestName, getImportInstance } from '@/bin/plugins/helpers'; + +import type { TanstackPlugin } from '../types'; + +import { + getApicraftTypeImport, + getMutationHook, + getQueryHook, + getSuspenseQueryHook, + getTanstackImport +} from '../helpers'; + +export const classHandler: TanstackPlugin['Handler'] = ({ plugin }) => { + const hooksFile = plugin.createFile({ + id: 'hooks', + path: `${plugin.output}/hooks` + }); + + const imports: ts.ImportDeclaration[] = [ + getTanstackImport(['useQuery', 'useMutation', 'queryOptions', 'useSuspenseQuery']), + getApicraftTypeImport([ + 'TanstackQuerySettings', + 'TanstackMutationSettings', + 'TanstackSuspenseQuerySettings' + ]), + getImportInstance({ + output: plugin.output, + folderPath: plugin.output, + generateOutput: plugin.config.generateOutput + }) + ]; + + const hooks: ts.VariableStatement[] = []; + + plugin.forEach('operation', (event) => { + if (event.type !== 'operation') return; + + const request = event.operation; + const requestName = generateRequestName(request, plugin.config.nameBy); + + hooks.push( + ...getQueryHook({ + hookName: `use${capitalize(requestName)}Query`, + plugin, + request, + requestName + }) + ); + hooks.push( + ...getMutationHook({ + hookName: `use${capitalize(requestName)}Mutation`, + plugin, + requestName + }) + ); + hooks.push( + ...getSuspenseQueryHook({ + hookName: `use${capitalize(requestName)}SuspenseQuery`, + optionsFunctionName: `${requestName}Options`, + plugin, + request, + requestName + }) + ); + }); + + hooksFile.add(...imports); + hooksFile.add(...hooks); +}; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts new file mode 100644 index 0000000..a67323c --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts @@ -0,0 +1,61 @@ +import type { DefinePlugin } from '@hey-api/openapi-ts'; + +import * as nodePath from 'node:path'; + +import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; + +import type { TanstackPluginConfig } from '../../types'; + +import { getApicraftTypeImport, getMutationHook, getTanstackImport } from '../../helpers'; + +interface GenerateMutationHookFileParams { + plugin: Parameters['Handler']>[0]['plugin']; + requestFilePath: string; + requestName: string; +} + +export const generateMutationHookFile = ({ + plugin, + requestName, + requestFilePath +}: GenerateMutationHookFileParams) => { + const hookName = `use${capitalize(requestName)}Mutation`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); + const hookFile = plugin.createFile({ + id: hookName, + path: hookFilePath + }); + + // import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; + hookFile.add(getApicraftTypeImport('TanstackMutationSettings')); + + // import { useMutation } from '@tanstack/react-query'; + hookFile.add(getTanstackImport('useMutation')); + + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + generateOutput: plugin.config.generateOutput + }) + ); + } + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + folderPath: hookFolderPath, + requestFilePath, + requestName, + generateOutput: plugin.config.generateOutput + }) + ); + } + + // const requestNameMutationKey = requestName; + // const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation + hookFile.add(...getMutationHook({ hookName, plugin, requestName })); +}; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts new file mode 100644 index 0000000..26e66ee --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts @@ -0,0 +1,66 @@ +import type { IR } from '@hey-api/openapi-ts'; + +import * as nodePath from 'node:path'; + +import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; +import { + getApicraftTypeImport, + getQueryHook, + getTanstackImport +} from '@/bin/plugins/tanstack/helpers'; + +import type { TanstackPlugin } from '../../types'; + +interface GenerateQueryHookParams { + plugin: TanstackPlugin['Instance']; + request: IR.OperationObject; + requestFilePath: string; + requestName: string; +} + +export const generateQueryHookFile = ({ + plugin, + request, + requestName, + requestFilePath +}: GenerateQueryHookParams) => { + const hookName = `use${capitalize(requestName)}Query`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); + const hookFile = plugin.createFile({ + id: hookName, + path: hookFilePath + }); + + // import type { TanstackQuerySettings } from '@siberiacancode/apicraft'; + hookFile.add(getApicraftTypeImport('TanstackQuerySettings')); + + // import { useQuery } from '@tanstack/react-query'; + hookFile.add(getTanstackImport('useQuery')); + + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + generateOutput: plugin.config.generateOutput + }) + ); + } + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + folderPath: hookFolderPath, + requestFilePath, + requestName, + generateOutput: plugin.config.generateOutput + }) + ); + } + + // const requestNameQueryKey = requestName; + // const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery + hookFile.add(...getQueryHook({ hookName, request, plugin, requestName })); +}; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts new file mode 100644 index 0000000..e66aa54 --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts @@ -0,0 +1,72 @@ +import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; + +import * as nodePath from 'node:path'; + +import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; + +import type { TanstackPluginConfig } from '../../types'; + +import { getApicraftTypeImport, getSuspenseQueryHook, getTanstackImport } from '../../helpers'; + +interface GenerateSuspenseQueryHookParams { + plugin: Parameters['Handler']>[0]['plugin']; + request: IR.OperationObject; + requestFilePath: string; + requestName: string; +} + +export const generateSuspenseQueryHookFile = ({ + plugin, + request, + requestName, + requestFilePath +}: GenerateSuspenseQueryHookParams) => { + const hookName = `use${capitalize(requestName)}SuspenseQuery`; + const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; + const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); + const hookFile = plugin.createFile({ + id: hookName, + path: hookFilePath + }); + + // import type { TanstackSuspenseQuerySettings } from '@siberiacancode/apicraft'; + hookFile.add(getApicraftTypeImport('TanstackSuspenseQuerySettings')); + + // import { queryOptions, useSuspenseQuery } from '@tanstack/react-query'; + hookFile.add(getTanstackImport(['queryOptions', 'useSuspenseQuery'])); + + if (plugin.config.groupBy === 'class') { + // import { instance } from '../../instance.gen'; + hookFile.add( + getImportInstance({ + output: plugin.output, + folderPath: hookFolderPath, + generateOutput: plugin.config.generateOutput + }) + ); + } + if (plugin.config.groupBy !== 'class') { + // import type { requestName } from './requestName.gen'; + hookFile.add( + getImportRequest({ + folderPath: hookFolderPath, + requestFilePath, + requestName, + generateOutput: plugin.config.generateOutput + }) + ); + } + + // const requestNameSuspenseQueryKey = requestName; + // const requestNameOptions = queryOptions({...}) + // const useRequestNameSuspenseQuery = (settings: TanstackSuspenseQuerySettings) => useSuspenseQuery + hookFile.add( + ...getSuspenseQueryHook({ + optionsFunctionName: `${requestName}Options`, + hookName, + plugin, + request, + requestName + }) + ); +}; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/index.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/index.ts new file mode 100644 index 0000000..cc8eba0 --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/index.ts @@ -0,0 +1,3 @@ +export * from './generateMutationHookFile'; +export * from './generateQueryHookFile'; +export * from './generateSuspenseQueryHookFile'; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/plugin.ts b/packages/apicraft/bin/plugins/tanstack/composed/plugin.ts new file mode 100644 index 0000000..0dc299c --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/composed/plugin.ts @@ -0,0 +1,30 @@ +import { generateRequestName, getRequestFilePaths } from '@/bin/plugins/helpers'; + +import type { TanstackPlugin } from '../types'; + +import { + generateMutationHookFile, + generateQueryHookFile, + generateSuspenseQueryHookFile +} from './helpers'; + +export const composedHandler: TanstackPlugin['Handler'] = ({ plugin }) => + plugin.forEach('operation', (event) => { + if (event.type !== 'operation') return; + + const request = event.operation; + const requestName = generateRequestName(request, plugin.config.nameBy); + + const requestFilePaths = getRequestFilePaths({ + groupBy: plugin.config.groupBy, + output: plugin.output, + requestName, + request + }); + + requestFilePaths.forEach((requestFilePath) => { + generateQueryHookFile({ plugin, requestFilePath, request, requestName }); + generateSuspenseQueryHookFile({ plugin, requestFilePath, request, requestName }); + generateMutationHookFile({ plugin, requestFilePath, requestName }); + }); + }); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts new file mode 100644 index 0000000..1192b55 --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts @@ -0,0 +1,17 @@ +import ts from 'typescript'; + +// import type { name } from '@siberiacancode/apicraft'; +export const getApicraftTypeImport = (name: string | string[]) => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + true, + undefined, + ts.factory.createNamedImports([ + ...(Array.isArray(name) ? name : [name]).map((name) => + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(name)) + ) + ]) + ), + ts.factory.createStringLiteral('@siberiacancode/apicraft') + ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts similarity index 54% rename from packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts rename to packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts index cb1cdd2..3e9de8f 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts @@ -1,72 +1,31 @@ -import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; - -import * as nodePath from 'node:path'; import ts from 'typescript'; -import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; - -import type { TanstackPluginConfig } from '../types'; +import type { TanstackPlugin } from '../types'; -import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; - -interface GenerateMutationHookFileParams { - plugin: Parameters['Handler']>[0]['plugin']; - request: IR.OperationObject; - requestFilePath: string; +interface GetMutationHookParams { + hookName: string; + plugin: TanstackPlugin['Instance']; requestName: string; } -export const generateMutationHookFile = ({ - plugin, - request, - requestName, - requestFilePath -}: GenerateMutationHookFileParams) => { - const hookName = `use${capitalize(requestName)}Mutation`; - const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; - const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); - const hookFile = plugin.createFile({ - id: hookName, - path: hookFilePath - }); - - // import { useMutation } from '@tanstack/react-query'; - const importUseMutation = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, +// const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation +export const getMutationHook = ({ hookName, plugin, requestName }: GetMutationHookParams) => { + // export const requestNameMutationKey = requestName; + const mutationKey = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(`${requestName}MutationKey`), undefined, - ts.factory.createIdentifier('useMutation') - ) - ]) - ), - ts.factory.createStringLiteral('@tanstack/react-query') - ); - - // import type { TanstackMutationSettings } from '@siberiacancode/apicraft'; - const importTanstackMutationSettings = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - true, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, undefined, - ts.factory.createIdentifier('TanstackMutationSettings') + ts.factory.createStringLiteral(requestName) ) - ]) - ), - ts.factory.createStringLiteral('@siberiacancode/apicraft') + ], + ts.NodeFlags.Const + ) ); - const requestParamsHookKeys = getRequestParamsHookKeys(request); - - // const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation const hookFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( @@ -109,35 +68,16 @@ export const generateMutationHookFile = ({ ts.factory.createIdentifier('mutationKey'), ts.factory.createArrayLiteralExpression( [ - ts.factory.createStringLiteral(requestName), - ...requestParamsHookKeys.path.map((requestPathParam) => - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier('request') - ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier('path') - ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestPathParam) - ) - ), - ...requestParamsHookKeys.query.map((requestQueryParam) => + ts.factory.createStringLiteral(`${requestName}MutationKey`), + ...['path', 'query', 'body'].map((field) => ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier('request') - ), + ts.factory.createIdentifier('settings'), ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier('query') + ts.factory.createIdentifier('request') ), ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestQueryParam) + ts.factory.createIdentifier(field) ) ) ], @@ -206,30 +146,5 @@ export const generateMutationHookFile = ({ ) ); - hookFile.add(importUseMutation); - hookFile.add(importTanstackMutationSettings); - - if (plugin.config.groupBy === 'class') { - // import { instance } from '../../instance.gen'; - hookFile.add( - getImportInstance({ - output: plugin.output, - folderPath: hookFolderPath, - generateOutput: plugin.config.generateOutput - }) - ); - } - if (plugin.config.groupBy !== 'class') { - // import type { requestName } from './requestName.gen'; - hookFile.add( - getImportRequest({ - folderPath: hookFolderPath, - requestFilePath, - requestName, - generateOutput: plugin.config.generateOutput - }) - ); - } - - hookFile.add(hookFunction); + return [mutationKey, hookFunction]; }; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts similarity index 51% rename from packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts rename to packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts index 4f33655..27d8b58 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts @@ -1,75 +1,38 @@ -import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; +import type { IR } from '@hey-api/openapi-ts'; -import * as nodePath from 'node:path'; import ts from 'typescript'; -import { - capitalize, - getImportInstance, - getImportRequest, - getRequestInfo -} from '@/bin/plugins/helpers'; +import type { TanstackPlugin } from '../types'; -import type { TanstackPluginConfig } from '../types'; +import { getRequestInfo } from '../../helpers'; -import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; - -interface GenerateQueryHookParams { - plugin: Parameters['Handler']>[0]['plugin']; +interface GetQueryHookParams { + hookName: string; + plugin: TanstackPlugin['Instance']; request: IR.OperationObject; - requestFilePath: string; requestName: string; } -export const generateQueryHookFile = ({ - plugin, - request, - requestName, - requestFilePath -}: GenerateQueryHookParams) => { +// const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery +export const getQueryHook = ({ hookName, request, plugin, requestName }: GetQueryHookParams) => { const requestInfo = getRequestInfo({ request }); - const hookName = `use${capitalize(requestName)}Query`; - const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; - const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); - const hookFile = plugin.createFile({ - id: hookName, - path: hookFilePath - }); - - // import { useQuery } from '@tanstack/react-query'; - const importUseQuery = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier('useQuery')) - ]) - ), - ts.factory.createStringLiteral('@tanstack/react-query') - ); - - // import type { TanstackQuerySettings } from '@siberiacancode/apicraft'; - const importTanstackQuerySettings = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - true, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, + // export const requestNameQueryKey = requestName; + const queryKey = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(`${requestName}QueryKey`), + undefined, undefined, - ts.factory.createIdentifier('TanstackQuerySettings') + ts.factory.createStringLiteral(requestName) ) - ]) - ), - ts.factory.createStringLiteral('@siberiacancode/apicraft') + ], + ts.NodeFlags.Const + ) ); - const requestParamsHookKeys = getRequestParamsHookKeys(request); - - // const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery const hookFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( @@ -114,43 +77,20 @@ export const generateQueryHookFile = ({ ts.factory.createIdentifier('queryKey'), ts.factory.createArrayLiteralExpression( [ - ts.factory.createStringLiteral(requestName), - ...requestParamsHookKeys.path.map((requestPathParam) => + ts.factory.createStringLiteral(`${requestName}QueryKey`), + ...['path', 'query', 'body'].map((field) => ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('request') - ), + ts.factory.createIdentifier('settings'), !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, - ts.factory.createIdentifier('path') + ts.factory.createIdentifier('request') ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestPathParam) - ) - ), - ...requestParamsHookKeys.query.map((requestQueryParam) => - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('request') - ), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('query') - ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestQueryParam) + !requestInfo.hasRequiredParam + ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) + : undefined, + ts.factory.createIdentifier(field) ) ) ], @@ -214,30 +154,5 @@ export const generateQueryHookFile = ({ ) ); - hookFile.add(importUseQuery); - hookFile.add(importTanstackQuerySettings); - - if (plugin.config.groupBy === 'class') { - // import { instance } from '../../instance.gen'; - hookFile.add( - getImportInstance({ - output: plugin.output, - folderPath: hookFolderPath, - generateOutput: plugin.config.generateOutput - }) - ); - } - if (plugin.config.groupBy !== 'class') { - // import type { requestName } from './requestName.gen'; - hookFile.add( - getImportRequest({ - folderPath: hookFolderPath, - requestFilePath, - requestName, - generateOutput: plugin.config.generateOutput - }) - ); - } - - hookFile.add(hookFunction); + return [queryKey, hookFunction]; }; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getRequestParamsHookKeys.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getRequestParamsHookKeys.ts deleted file mode 100644 index 8f3cd0b..0000000 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getRequestParamsHookKeys.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { IR } from '@hey-api/openapi-ts'; - -export const getRequestParamsHookKeys = (request: IR.OperationObject) => ({ - path: Object.values(request.parameters?.path ?? {}) - .filter((param) => param.required) - .map((param) => param.name), - query: Object.values(request.parameters?.query ?? {}) - .filter((param) => param.required) - .map((param) => param.name) -}); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts similarity index 57% rename from packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts rename to packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts index a8f7e66..d447abc 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts @@ -1,84 +1,45 @@ -import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; +import type { IR } from '@hey-api/openapi-ts'; -import * as nodePath from 'node:path'; import ts from 'typescript'; -import { - capitalize, - getImportInstance, - getImportRequest, - getRequestInfo -} from '@/bin/plugins/helpers'; +import type { TanstackPlugin } from '../types'; -import type { TanstackPluginConfig } from '../types'; +import { getRequestInfo } from '../../helpers'; -import { getRequestParamsHookKeys } from './getRequestParamsHookKeys'; - -interface GenerateSuspenseQueryHookParams { - plugin: Parameters['Handler']>[0]['plugin']; +interface GetSuspenseQueryHookParams { + hookName: string; + optionsFunctionName: string; + plugin: TanstackPlugin['Instance']; request: IR.OperationObject; - requestFilePath: string; requestName: string; } -export const generateSuspenseQueryHookFile = ({ +// const useRequestNameSuspenseQuery = (settings: TanstackSuspenseQuerySettings) => useSuspenseQuery +export const getSuspenseQueryHook = ({ plugin, + optionsFunctionName, request, - requestName, - requestFilePath -}: GenerateSuspenseQueryHookParams) => { + hookName, + requestName +}: GetSuspenseQueryHookParams) => { const requestInfo = getRequestInfo({ request }); - const hookName = `use${capitalize(requestName)}SuspenseQuery`; - const hookFilePath = `${nodePath.dirname(requestFilePath).replace('requests', 'hooks')}/${hookName}`; - const hookFolderPath = nodePath.dirname(`${plugin.config.generateOutput}/${hookFilePath}`); - const hookFile = plugin.createFile({ - id: hookName, - path: hookFilePath - }); - - // import { queryOptions, useSuspenseQuery } from '@tanstack/react-query'; - const importUseSuspenseQuery = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, - undefined, - ts.factory.createIdentifier('queryOptions') - ), - ts.factory.createImportSpecifier( - false, + // export const requestNameSuspenseQueryKey = requestName; + const suspenseQueryKey = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(`${requestName}SuspenseQueryKey`), undefined, - ts.factory.createIdentifier('useSuspenseQuery') - ) - ]) - ), - ts.factory.createStringLiteral('@tanstack/react-query') - ); - - // import type { TanstackSuspenseQuerySettings } from '@siberiacancode/apicraft'; - const importTanstackSuspenseQuerySettings = ts.factory.createImportDeclaration( - undefined, - ts.factory.createImportClause( - true, - undefined, - ts.factory.createNamedImports([ - ts.factory.createImportSpecifier( - false, undefined, - ts.factory.createIdentifier('TanstackSuspenseQuerySettings') + ts.factory.createStringLiteral(requestName) ) - ]) - ), - ts.factory.createStringLiteral('@siberiacancode/apicraft') + ], + ts.NodeFlags.Const + ) ); - const optionsFunctionName = `${requestName}Options`; - const requestParamsHookKeys = getRequestParamsHookKeys(request); - // const requestNameOptions = queryOptions({...}) const optionsFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], @@ -127,43 +88,20 @@ export const generateSuspenseQueryHookFile = ({ ts.factory.createIdentifier('queryKey'), ts.factory.createArrayLiteralExpression( [ - ts.factory.createStringLiteral(requestName), - ...requestParamsHookKeys.path.map((requestPathParam) => + ts.factory.createStringLiteral(`${requestName}SuspenseQueryKey`), + ...['path', 'query', 'body'].map((field) => ts.factory.createPropertyAccessChain( ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('request') - ), + ts.factory.createIdentifier('settings'), !requestInfo.hasRequiredParam ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) : undefined, - ts.factory.createIdentifier('path') + ts.factory.createIdentifier('request') ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestPathParam) - ) - ), - ...requestParamsHookKeys.query.map((requestQueryParam) => - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('request') - ), - !requestInfo.hasRequiredParam - ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) - : undefined, - ts.factory.createIdentifier('query') - ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(requestQueryParam) + !requestInfo.hasRequiredParam + ? ts.factory.createToken(ts.SyntaxKind.QuestionDotToken) + : undefined, + ts.factory.createIdentifier(field) ) ) ], @@ -228,6 +166,7 @@ export const generateSuspenseQueryHookFile = ({ ) ); + // const useRequestNameSuspenseQuery = (settings: TanstackSuspenseQuerySettings) => useSuspenseQuery const hookFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( @@ -270,31 +209,5 @@ export const generateSuspenseQueryHookFile = ({ ) ); - hookFile.add(importUseSuspenseQuery); - hookFile.add(importTanstackSuspenseQuerySettings); - - if (plugin.config.groupBy === 'class') { - // import { instance } from '../../instance.gen'; - hookFile.add( - getImportInstance({ - output: plugin.output, - folderPath: hookFolderPath, - generateOutput: plugin.config.generateOutput - }) - ); - } - if (plugin.config.groupBy !== 'class') { - // import type { requestName } from './requestName.gen'; - hookFile.add( - getImportRequest({ - folderPath: hookFolderPath, - requestFilePath, - requestName, - generateOutput: plugin.config.generateOutput - }) - ); - } - - hookFile.add(optionsFunction); - hookFile.add(hookFunction); + return [suspenseQueryKey, optionsFunction, hookFunction]; }; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getTanstackImport.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getTanstackImport.ts new file mode 100644 index 0000000..cde9044 --- /dev/null +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getTanstackImport.ts @@ -0,0 +1,17 @@ +import ts from 'typescript'; + +// import { name } from '@tanstack/react-query'; +export const getTanstackImport = (name: string | string[]) => + ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + undefined, + ts.factory.createNamedImports([ + ...(Array.isArray(name) ? name : [name]).map((name) => + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(name)) + ) + ]) + ), + ts.factory.createStringLiteral('@tanstack/react-query') + ); diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/index.ts b/packages/apicraft/bin/plugins/tanstack/helpers/index.ts index cc8eba0..51c6fcf 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/index.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/index.ts @@ -1,3 +1,5 @@ -export * from './generateMutationHookFile'; -export * from './generateQueryHookFile'; -export * from './generateSuspenseQueryHookFile'; +export * from './getApicraftTypeImport'; +export * from './getMutationHook'; +export * from './getQueryHook'; +export * from './getSuspenseQueryHook'; +export * from './getTanstackImport'; diff --git a/packages/apicraft/bin/plugins/tanstack/plugin.ts b/packages/apicraft/bin/plugins/tanstack/plugin.ts index 7d3bb55..6468808 100644 --- a/packages/apicraft/bin/plugins/tanstack/plugin.ts +++ b/packages/apicraft/bin/plugins/tanstack/plugin.ts @@ -1,29 +1,7 @@ import type { TanstackPlugin } from './types'; -import { generateRequestName, getRequestFilePaths } from '../helpers'; -import { - generateMutationHookFile, - generateQueryHookFile, - generateSuspenseQueryHookFile -} from './helpers'; +import { classHandler } from './class/plugin'; +import { composedHandler } from './composed/plugin'; export const handler: TanstackPlugin['Handler'] = ({ plugin }) => - plugin.forEach('operation', (event) => { - if (event.type !== 'operation') return; - - const request = event.operation; - const requestName = generateRequestName(request, plugin.config.nameBy); - - const requestFilePaths = getRequestFilePaths({ - groupBy: plugin.config.groupBy, - output: plugin.output, - requestName, - request - }); - - requestFilePaths.forEach((requestFilePath) => { - generateQueryHookFile({ plugin, requestFilePath, request, requestName }); - generateSuspenseQueryHookFile({ plugin, requestFilePath, request, requestName }); - generateMutationHookFile({ plugin, requestFilePath, request, requestName }); - }); - }); + plugin.config.groupBy === 'class' ? classHandler({ plugin }) : composedHandler({ plugin }); diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts new file mode 100644 index 0000000..fa0a80a --- /dev/null +++ b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts @@ -0,0 +1,85 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { useQuery, useMutation, queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import type { TanstackQuerySettings, TanstackMutationSettings, TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + +import { instance } from "generated/apiV2-class-runtime-instance/instance.gen"; + +export const getUsersQueryKey = "getUsers"; + +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ + queryKey: ["getUsersQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + queryFn: async () => instance.getUsers({ ...settings?.request }), + ...settings?.params +}); + +export const getUsersMutationKey = "getUsers"; + +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["getUsersMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), + ...settings?.params +}); + +export const getUsersSuspenseQueryKey = "getUsers"; + +export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["getUsersSuspenseQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + queryFn: async () => instance.getUsers({ ...settings?.request }), + ...settings?.params +}); + +export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); + +export const putUserByUsernameQueryKey = "putUserByUsername"; + +export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["putUserByUsernameQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => instance.putUserByUsername({ ...settings.request }), + ...settings.params +}); + +export const putUserByUsernameMutationKey = "putUserByUsername"; + +export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["putUserByUsernameMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), + ...settings?.params +}); + +export const putUserByUsernameSuspenseQueryKey = "putUserByUsername"; + +export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["putUserByUsernameSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => instance.putUserByUsername({ ...settings.request }), + ...settings.params +}); + +export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); + +export const postEchoQueryKey = "postEcho"; + +export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["postEchoQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => instance.postEcho({ ...settings.request }), + ...settings.params +}); + +export const postEchoMutationKey = "postEcho"; + +export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["postEchoMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), + ...settings?.params +}); + +export const postEchoSuspenseQueryKey = "postEcho"; + +export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["postEchoSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => instance.postEcho({ ...settings.request }), + ...settings.params +}); + +export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts deleted file mode 100644 index e985002..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["postEcho"], - mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts deleted file mode 100644 index 9e8214c..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["postEcho"], - queryFn: async () => instance.postEcho({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts deleted file mode 100644 index 94a0298..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/Echo/usePostEchoSuspenseQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["postEcho"], - queryFn: async () => instance.postEcho({ ...settings.request }), - ...settings.params -}); - -export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts deleted file mode 100644 index 9f00a9e..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["putUserByUsername", settings?.request?.path?.username], - mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts deleted file mode 100644 index 6a921b0..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts deleted file mode 100644 index fb21611..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), - ...settings.params -}); - -export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts deleted file mode 100644 index 2f3c62c..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["getUsers"], - mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts deleted file mode 100644 index 8841351..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ - queryKey: ["getUsers"], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts index 75b106f..724a162 100644 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts +++ b/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts @@ -1,12 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts export * from './types.gen'; -export * from './hooks/default/useGetUsersQuery.gen'; -export * from './hooks/default/useGetUsersSuspenseQuery.gen'; -export * from './hooks/default/useGetUsersMutation.gen'; -export * from './hooks/User/usePutUserByUsernameQuery.gen'; -export * from './hooks/User/usePutUserByUsernameSuspenseQuery.gen'; -export * from './hooks/User/usePutUserByUsernameMutation.gen'; -export * from './hooks/Echo/usePostEchoQuery.gen'; -export * from './hooks/Echo/usePostEchoSuspenseQuery.gen'; -export * from './hooks/Echo/usePostEchoMutation.gen'; +export * from './hooks.gen'; export * from './instance.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts index 5696b65..a8f51b7 100644 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts +++ b/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts @@ -1,18 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { AxiosRequestParams } from '@siberiacancode/apicraft'; +import type { AxiosRequestParams } from "@siberiacancode/apicraft"; -import type { - GetUserByNameData, - GetUserByNameResponse, - UpdateUserData, - EchoData, - EchoResponse -} from './types.gen'; +import type { GetUserByNameData, GetUserByNameResponse, UpdateUserData, EchoData, EchoResponse } from "./types.gen"; -import type { AxiosInstance } from 'axios'; +import type { AxiosInstance } from "axios"; -import { instance as runtimeInstance } from '../../src/test-runtime'; +import { instance as runtimeInstance } from "../../src/test-runtime"; export type GetUsersRequestParams = AxiosRequestParams; @@ -21,35 +15,35 @@ export type PutUserByUsernameRequestParams = AxiosRequestParams; export type PostEchoRequestParams = AxiosRequestParams; export class ApiInstance { - private instance: AxiosInstance; - constructor() { - this.instance = runtimeInstance; - } - getUsers({ config, query }: GetUsersRequestParams = {}) { - return this.instance.request({ - method: 'GET', - url: '/users', - params: query, - ...config - }); - } - putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { - return this.instance.request({ - method: 'PUT', - url: `/users/${path.username}`, - data: body, - params: query, - ...config - }); - } - postEcho({ config, body }: PostEchoRequestParams) { - return this.instance.request({ - method: 'POST', - url: '/echo', - data: body, - ...config - }); - } + private instance: AxiosInstance; + constructor() { + this.instance = runtimeInstance; + } + getUsers({ config, query }: GetUsersRequestParams = {}) { + return this.instance.request({ + method: "GET", + url: "/users", + params: query, + ...config + }); + } + putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { + return this.instance.request({ + method: "PUT", + url: `/users/${path.username}`, + data: body, + params: query, + ...config + }); + } + postEcho({ config, body }: PostEchoRequestParams) { + return this.instance.request({ + method: "POST", + url: "/echo", + data: body, + ...config + }); + } } -export const instance = new ApiInstance(); +export const instance = new ApiInstance(); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts deleted file mode 100644 index e985002..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["postEcho"], - mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts deleted file mode 100644 index 9e8214c..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["postEcho"], - queryFn: async () => instance.postEcho({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts deleted file mode 100644 index 9f00a9e..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["putUserByUsername", settings?.request?.path?.username], - mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts deleted file mode 100644 index 6a921b0..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts deleted file mode 100644 index 2f3c62c..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersMutation.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useMutation } from "@tanstack/react-query"; - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["getUsers"], - mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts deleted file mode 100644 index 8841351..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersQuery.gen.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ - queryKey: ["getUsers"], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts deleted file mode 100644 index 851b8dc..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/default/useGetUsersSuspenseQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "../../instance.gen"; - -export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["getUsers"], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params -}); - -export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts new file mode 100644 index 0000000..eee41a4 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { useMutation } from "@tanstack/react-query"; + +import { postEcho } from "../../requests/echo/post.gen"; + +export const postEchoMutationKey = "postEcho"; + +export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["postEchoMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => postEcho({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts new file mode 100644 index 0000000..36dbcd6 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { useQuery } from "@tanstack/react-query"; + +import { postEcho } from "../../requests/echo/post.gen"; + +export const postEchoQueryKey = "postEcho"; + +export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["postEchoQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => postEcho({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts similarity index 56% rename from packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts index 94a0298..1c1c4d9 100644 --- a/packages/apicraft/generated/apiV2-class/hooks/Echo/usePostEchoSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts @@ -1,14 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; +import { postEcho } from "../../requests/echo/post.gen"; -import { instance } from "../../instance.gen"; +export const postEchoSuspenseQueryKey = "postEcho"; -export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["postEcho"], - queryFn: async () => instance.postEcho({ ...settings.request }), +export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["postEchoSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => postEcho({ ...settings.request }), ...settings.params }); diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts new file mode 100644 index 0000000..09e995e --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { useMutation } from "@tanstack/react-query"; + +import { getUsers } from "../../requests/users/get.gen"; + +export const getUsersMutationKey = "getUsers"; + +export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["getUsersMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => getUsers({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts new file mode 100644 index 0000000..69b5688 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { useQuery } from "@tanstack/react-query"; + +import { getUsers } from "../../requests/users/get.gen"; + +export const getUsersQueryKey = "getUsers"; + +export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ + queryKey: ["getUsersQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + queryFn: async () => getUsers({ ...settings?.request }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts similarity index 56% rename from packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts index 851b8dc..39f6c6c 100644 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks/default/useGetUsersSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts @@ -1,14 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; +import { getUsers } from "../../requests/users/get.gen"; -import { instance } from "../../instance.gen"; +export const getUsersSuspenseQueryKey = "getUsers"; -export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["getUsers"], - queryFn: async () => instance.getUsers({ ...settings?.request }), +export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["getUsersSuspenseQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + queryFn: async () => getUsers({ ...settings?.request }), ...settings?.params }); diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts new file mode 100644 index 0000000..9c43beb --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; + +import { useMutation } from "@tanstack/react-query"; + +import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; + +export const putUserByUsernameMutationKey = "putUserByUsername"; + +export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ + mutationKey: ["putUserByUsernameMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], + mutationFn: async (params) => putUserByUsername({ ...settings?.request, ...params }), + ...settings?.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts new file mode 100644 index 0000000..0e64cde --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; + +import { useQuery } from "@tanstack/react-query"; + +import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; + +export const putUserByUsernameQueryKey = "putUserByUsername"; + +export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ + queryKey: ["putUserByUsernameQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => putUserByUsername({ ...settings.request }), + ...settings.params +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts similarity index 53% rename from packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts rename to packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts index fb21611..86f9129 100644 --- a/packages/apicraft/generated/apiV2-class/hooks/User/usePutUserByUsernameSuspenseQuery.gen.ts +++ b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts @@ -1,14 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts +import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; + import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; +import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; -import { instance } from "../../instance.gen"; +export const putUserByUsernameSuspenseQueryKey = "putUserByUsername"; -export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["putUserByUsername", settings.request.path?.username], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), +export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ + queryKey: ["putUserByUsernameSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], + queryFn: async () => putUserByUsername({ ...settings.request }), ...settings.params }); diff --git a/packages/apicraft/generated/apiV2-class/index.ts b/packages/apicraft/generated/apiV2-class/index.ts index 75b106f..7db27e0 100644 --- a/packages/apicraft/generated/apiV2-class/index.ts +++ b/packages/apicraft/generated/apiV2-class/index.ts @@ -1,12 +1,15 @@ // This file is auto-generated by @hey-api/openapi-ts export * from './types.gen'; -export * from './hooks/default/useGetUsersQuery.gen'; -export * from './hooks/default/useGetUsersSuspenseQuery.gen'; -export * from './hooks/default/useGetUsersMutation.gen'; -export * from './hooks/User/usePutUserByUsernameQuery.gen'; -export * from './hooks/User/usePutUserByUsernameSuspenseQuery.gen'; -export * from './hooks/User/usePutUserByUsernameMutation.gen'; -export * from './hooks/Echo/usePostEchoQuery.gen'; -export * from './hooks/Echo/usePostEchoSuspenseQuery.gen'; -export * from './hooks/Echo/usePostEchoMutation.gen'; -export * from './instance.gen'; \ No newline at end of file +export * from './hooks/users/useGetUsersQuery.gen'; +export * from './hooks/users/useGetUsersSuspenseQuery.gen'; +export * from './hooks/users/useGetUsersMutation.gen'; +export * from './hooks/users/{username}/usePutUserByUsernameQuery.gen'; +export * from './hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen'; +export * from './hooks/users/{username}/usePutUserByUsernameMutation.gen'; +export * from './hooks/echo/usePostEchoQuery.gen'; +export * from './hooks/echo/usePostEchoSuspenseQuery.gen'; +export * from './hooks/echo/usePostEchoMutation.gen'; +export * from './instance.gen'; +export * from './requests/users/get.gen'; +export * from './requests/users/{username}/put.gen'; +export * from './requests/echo/post.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/instance.gen.ts b/packages/apicraft/generated/apiV2-class/instance.gen.ts index e284481..c3838e0 100644 --- a/packages/apicraft/generated/apiV2-class/instance.gen.ts +++ b/packages/apicraft/generated/apiV2-class/instance.gen.ts @@ -1,55 +1,5 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { AxiosRequestParams } from '@siberiacancode/apicraft'; +import axios from "axios"; -import type { - GetUserByNameData, - GetUserByNameResponse, - UpdateUserData, - EchoData, - EchoResponse -} from './types.gen'; - -import type { AxiosInstance, CreateAxiosDefaults } from 'axios'; - -import axios from 'axios'; - -export type GetUsersRequestParams = AxiosRequestParams; - -export type PutUserByUsernameRequestParams = AxiosRequestParams; - -export type PostEchoRequestParams = AxiosRequestParams; - -export class ApiInstance { - private instance: AxiosInstance; - constructor(config?: CreateAxiosDefaults) { - this.instance = axios.create(config); - } - getUsers({ config, query }: GetUsersRequestParams = {}) { - return this.instance.request({ - method: 'GET', - url: '/users', - params: query, - ...config - }); - } - putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { - return this.instance.request({ - method: 'PUT', - url: `/users/${path.username}`, - data: body, - params: query, - ...config - }); - } - postEcho({ config, body }: PostEchoRequestParams) { - return this.instance.request({ - method: 'POST', - url: '/echo', - data: body, - ...config - }); - } -} - -export const instance = new ApiInstance(); +export const instance = axios.create(); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts b/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts new file mode 100644 index 0000000..9311e68 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosRequestParams } from "@siberiacancode/apicraft"; + +import type { EchoData, EchoResponse } from "../../types.gen"; + +import { instance } from "../../instance.gen"; + +export type PostEchoRequestParams = AxiosRequestParams; + +export const postEcho = ({ config, body }: PostEchoRequestParams) => instance.request({ + method: "POST", + url: "/echo", + data: body, + ...config +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts b/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts new file mode 100644 index 0000000..f087f49 --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosRequestParams } from "@siberiacancode/apicraft"; + +import type { GetUserByNameData, GetUserByNameResponse } from "../../types.gen"; + +import { instance } from "../../instance.gen"; + +export type GetUsersRequestParams = AxiosRequestParams; + +export const getUsers = ({ config, query }: GetUsersRequestParams = {}) => instance.request({ + method: "GET", + url: "/users", + params: query, + ...config +}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts b/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts new file mode 100644 index 0000000..52ffe6a --- /dev/null +++ b/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts @@ -0,0 +1,17 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosRequestParams } from "@siberiacancode/apicraft"; + +import type { UpdateUserData } from "../../../types.gen"; + +import { instance } from "../../../instance.gen"; + +export type PutUserByUsernameRequestParams = AxiosRequestParams; + +export const putUserByUsername = ({ config, body, query, path }: PutUserByUsernameRequestParams) => instance.request({ + method: "PUT", + url: `/users/${path.username}`, + data: body, + params: query, + ...config +}); \ No newline at end of file From 9050e3aeb5f8fb073efe23133514b4ede4be3488 Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Fri, 27 Feb 2026 16:31:38 +0700 Subject: [PATCH 08/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20camelCase=20for=20=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apicraft/bin/plugins/helpers/generatePathRequestName.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts index 8d32079..6a058bf 100644 --- a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts +++ b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts @@ -7,7 +7,7 @@ export const generatePathRequestName = (method: string, path: string) => { let prevPart: string | undefined; for (let pathPart of pathParts) { - pathPart = pathPart.split('-').filter(Boolean).map(capitalize).join(''); + pathPart = pathPart.split(/[-_]/).filter(Boolean).map(capitalize).join(''); const isParam = pathPart.startsWith('{') && pathPart.endsWith('}'); if (!isParam) { From 67950cc78b1d71b04919d14b3786375106a0e05a Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 28 Feb 2026 19:38:47 +0700 Subject: [PATCH 09/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20review=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apicraft/bin/plugins/axios/class/plugin.ts | 10 +++++++--- .../apicraft/bin/plugins/axios/helpers/index.ts | 1 - packages/apicraft/bin/plugins/axios/plugin.ts | 10 ++++++++-- .../plugins/helpers/generatePathRequestName.ts | 6 +++++- .../imports}/getApicraftTypeImport.ts | 0 .../imports}/getImportRuntimeInstance.ts | 0 .../bin/plugins/helpers/imports/index.ts | 2 ++ .../bin/plugins/tanstack/class/plugin.ts | 15 +++++++-------- .../helpers/generateMutationHookFile.ts | 11 ++++++++--- .../composed/helpers/generateQueryHookFile.ts | 11 ++++++----- .../helpers/generateSuspenseQueryHookFile.ts | 11 ++++++++--- .../plugins/tanstack/helpers/getMutationHook.ts | 17 ++--------------- .../plugins/tanstack/helpers/getQueryHook.ts | 2 +- .../tanstack/helpers/getSuspenseQueryHook.ts | 2 +- .../bin/plugins/tanstack/helpers/index.ts | 1 - .../apicraft/bin/plugins/tanstack/plugin.ts | 10 ++++++++-- 16 files changed, 63 insertions(+), 46 deletions(-) rename packages/apicraft/bin/plugins/{tanstack/helpers => helpers/imports}/getApicraftTypeImport.ts (100%) rename packages/apicraft/bin/plugins/{axios/helpers => helpers/imports}/getImportRuntimeInstance.ts (100%) diff --git a/packages/apicraft/bin/plugins/axios/class/plugin.ts b/packages/apicraft/bin/plugins/axios/class/plugin.ts index e816e0c..dc0bd1b 100644 --- a/packages/apicraft/bin/plugins/axios/class/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/class/plugin.ts @@ -1,7 +1,12 @@ import * as nodePath from 'node:path'; import ts from 'typescript'; -import { capitalize, generateRequestName, getRequestInfo } from '@/bin/plugins/helpers'; +import { + capitalize, + generateRequestName, + getImportRuntimeInstance, + getRequestInfo +} from '@/bin/plugins/helpers'; import type { AxiosPlugin } from '../types'; @@ -10,8 +15,7 @@ import { getAxiosRequestParameterDeclaration, getAxiosRequestParamsType, getImportAxios, - getImportAxiosRequestParams, - getImportRuntimeInstance + getImportAxiosRequestParams } from '../helpers'; const CLASS_NAME = 'ApiInstance'; diff --git a/packages/apicraft/bin/plugins/axios/helpers/index.ts b/packages/apicraft/bin/plugins/axios/helpers/index.ts index 1a04759..4d25b88 100644 --- a/packages/apicraft/bin/plugins/axios/helpers/index.ts +++ b/packages/apicraft/bin/plugins/axios/helpers/index.ts @@ -4,4 +4,3 @@ export * from './getAxiosRequestParameterDeclaration'; export * from './getAxiosRequestParamsType'; export * from './getImportAxios'; export * from './getImportAxiosRequestParams'; -export * from './getImportRuntimeInstance'; diff --git a/packages/apicraft/bin/plugins/axios/plugin.ts b/packages/apicraft/bin/plugins/axios/plugin.ts index 68f76ab..505ea72 100644 --- a/packages/apicraft/bin/plugins/axios/plugin.ts +++ b/packages/apicraft/bin/plugins/axios/plugin.ts @@ -3,5 +3,11 @@ import type { AxiosPlugin } from './types'; import { classHandler } from './class/plugin'; import { composedHandler } from './composed/plugin'; -export const handler: AxiosPlugin['Handler'] = ({ plugin }) => - plugin.config.groupBy === 'class' ? classHandler({ plugin }) : composedHandler({ plugin }); +export const handler: AxiosPlugin['Handler'] = ({ plugin }) => { + if (plugin.config.groupBy === 'class') { + classHandler({ plugin }); + } + if (plugin.config.groupBy === 'paths' || plugin.config.groupBy === 'tags') { + composedHandler({ plugin }); + } +}; diff --git a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts index 6a058bf..77060e7 100644 --- a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts +++ b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts @@ -7,7 +7,11 @@ export const generatePathRequestName = (method: string, path: string) => { let prevPart: string | undefined; for (let pathPart of pathParts) { - pathPart = pathPart.split(/[-_]/).filter(Boolean).map(capitalize).join(''); + pathPart = pathPart + .split(/[-_.*@]/) + .filter(Boolean) + .map(capitalize) + .join(''); const isParam = pathPart.startsWith('{') && pathPart.endsWith('}'); if (!isParam) { diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts b/packages/apicraft/bin/plugins/helpers/imports/getApicraftTypeImport.ts similarity index 100% rename from packages/apicraft/bin/plugins/tanstack/helpers/getApicraftTypeImport.ts rename to packages/apicraft/bin/plugins/helpers/imports/getApicraftTypeImport.ts diff --git a/packages/apicraft/bin/plugins/axios/helpers/getImportRuntimeInstance.ts b/packages/apicraft/bin/plugins/helpers/imports/getImportRuntimeInstance.ts similarity index 100% rename from packages/apicraft/bin/plugins/axios/helpers/getImportRuntimeInstance.ts rename to packages/apicraft/bin/plugins/helpers/imports/getImportRuntimeInstance.ts diff --git a/packages/apicraft/bin/plugins/helpers/imports/index.ts b/packages/apicraft/bin/plugins/helpers/imports/index.ts index 84bfd29..c6bc18c 100644 --- a/packages/apicraft/bin/plugins/helpers/imports/index.ts +++ b/packages/apicraft/bin/plugins/helpers/imports/index.ts @@ -1,2 +1,4 @@ +export * from './getApicraftTypeImport'; export * from './getImportInstance'; export * from './getImportRequest'; +export * from './getImportRuntimeInstance'; diff --git a/packages/apicraft/bin/plugins/tanstack/class/plugin.ts b/packages/apicraft/bin/plugins/tanstack/class/plugin.ts index 216ed54..0d46f72 100644 --- a/packages/apicraft/bin/plugins/tanstack/class/plugin.ts +++ b/packages/apicraft/bin/plugins/tanstack/class/plugin.ts @@ -1,16 +1,15 @@ import type ts from 'typescript'; -import { capitalize, generateRequestName, getImportInstance } from '@/bin/plugins/helpers'; +import { + capitalize, + generateRequestName, + getApicraftTypeImport, + getImportInstance +} from '@/bin/plugins/helpers'; import type { TanstackPlugin } from '../types'; -import { - getApicraftTypeImport, - getMutationHook, - getQueryHook, - getSuspenseQueryHook, - getTanstackImport -} from '../helpers'; +import { getMutationHook, getQueryHook, getSuspenseQueryHook, getTanstackImport } from '../helpers'; export const classHandler: TanstackPlugin['Handler'] = ({ plugin }) => { const hooksFile = plugin.createFile({ diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts index a67323c..cf910e6 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts @@ -2,11 +2,16 @@ import type { DefinePlugin } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; -import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; +import { + capitalize, + getApicraftTypeImport, + getImportInstance, + getImportRequest +} from '@/bin/plugins/helpers'; import type { TanstackPluginConfig } from '../../types'; -import { getApicraftTypeImport, getMutationHook, getTanstackImport } from '../../helpers'; +import { getMutationHook, getTanstackImport } from '../../helpers'; interface GenerateMutationHookFileParams { plugin: Parameters['Handler']>[0]['plugin']; @@ -43,7 +48,7 @@ export const generateMutationHookFile = ({ }) ); } - if (plugin.config.groupBy !== 'class') { + if (plugin.config.groupBy === 'paths' || plugin.config.groupBy === 'tags') { // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts index 26e66ee..8c9db29 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts @@ -2,12 +2,13 @@ import type { IR } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; -import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; import { + capitalize, getApicraftTypeImport, - getQueryHook, - getTanstackImport -} from '@/bin/plugins/tanstack/helpers'; + getImportInstance, + getImportRequest +} from '@/bin/plugins/helpers'; +import { getQueryHook, getTanstackImport } from '@/bin/plugins/tanstack/helpers'; import type { TanstackPlugin } from '../../types'; @@ -48,7 +49,7 @@ export const generateQueryHookFile = ({ }) ); } - if (plugin.config.groupBy !== 'class') { + if (plugin.config.groupBy === 'paths' || plugin.config.groupBy === 'tags') { // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts index e66aa54..55bdf86 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts @@ -2,11 +2,16 @@ import type { DefinePlugin, IR } from '@hey-api/openapi-ts'; import * as nodePath from 'node:path'; -import { capitalize, getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; +import { + capitalize, + getApicraftTypeImport, + getImportInstance, + getImportRequest +} from '@/bin/plugins/helpers'; import type { TanstackPluginConfig } from '../../types'; -import { getApicraftTypeImport, getSuspenseQueryHook, getTanstackImport } from '../../helpers'; +import { getSuspenseQueryHook, getTanstackImport } from '../../helpers'; interface GenerateSuspenseQueryHookParams { plugin: Parameters['Handler']>[0]['plugin']; @@ -45,7 +50,7 @@ export const generateSuspenseQueryHookFile = ({ }) ); } - if (plugin.config.groupBy !== 'class') { + if (plugin.config.groupBy === 'paths' || plugin.config.groupBy === 'tags') { // import type { requestName } from './requestName.gen'; hookFile.add( getImportRequest({ diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts index 3e9de8f..b834696 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts @@ -60,27 +60,14 @@ export const getMutationHook = ({ hookName, plugin, requestName }: GetMutationHo ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - // mutationKey: ['requestName', settings?.request?.path?.pathPart, settings?.request?.query?.someQuery], + // mutationKey: [requestNameMutationKey], ts.factory.createCallExpression(ts.factory.createIdentifier('useMutation'), undefined, [ ts.factory.createObjectLiteralExpression( [ ts.factory.createPropertyAssignment( ts.factory.createIdentifier('mutationKey'), ts.factory.createArrayLiteralExpression( - [ - ts.factory.createStringLiteral(`${requestName}MutationKey`), - ...['path', 'query', 'body'].map((field) => - ts.factory.createPropertyAccessChain( - ts.factory.createPropertyAccessChain( - ts.factory.createIdentifier('settings'), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier('request') - ), - ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), - ts.factory.createIdentifier(field) - ) - ) - ], + [ts.factory.createStringLiteral(`${requestName}MutationKey`)], false ) ), diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts index 27d8b58..1485adf 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts @@ -72,7 +72,7 @@ export const getQueryHook = ({ hookName, request, plugin, requestName }: GetQuer ts.factory.createCallExpression(ts.factory.createIdentifier('useQuery'), undefined, [ ts.factory.createObjectLiteralExpression( [ - // queryKey: ['requestName', settings.request.path.pathPart] + // queryKey: [requestNameQueryKey, settings.request.path, settings.request.query, settings.request.body] ts.factory.createPropertyAssignment( ts.factory.createIdentifier('queryKey'), ts.factory.createArrayLiteralExpression( diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts index d447abc..fc154dc 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts @@ -83,7 +83,7 @@ export const getSuspenseQueryHook = ({ [ ts.factory.createObjectLiteralExpression( [ - // queryKey: ['requestName', settings.request.path.pathPart] + // queryKey: [requestNameSuspenseQueryKey, settings.request.path, settings.request.query, settings.request.body] ts.factory.createPropertyAssignment( ts.factory.createIdentifier('queryKey'), ts.factory.createArrayLiteralExpression( diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/index.ts b/packages/apicraft/bin/plugins/tanstack/helpers/index.ts index 51c6fcf..5611b1c 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/index.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/index.ts @@ -1,4 +1,3 @@ -export * from './getApicraftTypeImport'; export * from './getMutationHook'; export * from './getQueryHook'; export * from './getSuspenseQueryHook'; diff --git a/packages/apicraft/bin/plugins/tanstack/plugin.ts b/packages/apicraft/bin/plugins/tanstack/plugin.ts index 6468808..d6fc303 100644 --- a/packages/apicraft/bin/plugins/tanstack/plugin.ts +++ b/packages/apicraft/bin/plugins/tanstack/plugin.ts @@ -3,5 +3,11 @@ import type { TanstackPlugin } from './types'; import { classHandler } from './class/plugin'; import { composedHandler } from './composed/plugin'; -export const handler: TanstackPlugin['Handler'] = ({ plugin }) => - plugin.config.groupBy === 'class' ? classHandler({ plugin }) : composedHandler({ plugin }); +export const handler: TanstackPlugin['Handler'] = ({ plugin }) => { + if (plugin.config.groupBy === 'class') { + classHandler({ plugin }); + } + if (plugin.config.groupBy === 'paths' || plugin.config.groupBy === 'tags') { + composedHandler({ plugin }); + } +}; From 02325c4093c245df50668ad78a941c7761dca0c9 Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sat, 28 Feb 2026 20:01:33 +0700 Subject: [PATCH 10/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20fix=20path=20request=20name=20generation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bin/plugins/helpers/generatePathRequestName.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts index 77060e7..7d62ec2 100644 --- a/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts +++ b/packages/apicraft/bin/plugins/helpers/generatePathRequestName.ts @@ -7,12 +7,12 @@ export const generatePathRequestName = (method: string, path: string) => { let prevPart: string | undefined; for (let pathPart of pathParts) { + const isParam = pathPart.startsWith('{') && pathPart.endsWith('}'); pathPart = pathPart - .split(/[-_.*@]/) + .split(/[^a-z0-9]+/i) .filter(Boolean) .map(capitalize) .join(''); - const isParam = pathPart.startsWith('{') && pathPart.endsWith('}'); if (!isParam) { nameParts.push(capitalize(pathPart)); @@ -27,9 +27,7 @@ export const generatePathRequestName = (method: string, path: string) => { prevPart.slice(0, -1).charAt(0).toUpperCase() + prevPart.slice(1, -1); } - const paramName = pathPart.slice(1, -1); - nameParts.push(`By${capitalize(paramName)}`); - + nameParts.push(`By${capitalize(pathPart)}`); prevPart = pathPart; } From eddfd0a392be8f3057ac3fe709185a898731687e Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sun, 1 Mar 2026 14:05:30 +0700 Subject: [PATCH 11/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20remove=20generated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/apicraft/apicraft.config.ts | 8 -- .../apiV2-class-runtime-instance/hooks.gen.ts | 85 ------------- .../apiV2-class-runtime-instance/index.ts | 4 - .../instance.gen.ts | 49 -------- .../apiV2-class-runtime-instance/types.gen.ts | 115 ------------------ .../hooks/echo/usePostEchoMutation.gen.ts | 15 --- .../hooks/echo/usePostEchoQuery.gen.ts | 15 --- .../echo/usePostEchoSuspenseQuery.gen.ts | 17 --- .../hooks/users/useGetUsersMutation.gen.ts | 15 --- .../hooks/users/useGetUsersQuery.gen.ts | 15 --- .../users/useGetUsersSuspenseQuery.gen.ts | 17 --- .../usePutUserByUsernameMutation.gen.ts | 15 --- .../usePutUserByUsernameQuery.gen.ts | 15 --- .../usePutUserByUsernameSuspenseQuery.gen.ts | 17 --- .../apicraft/generated/apiV2-class/index.ts | 15 --- .../generated/apiV2-class/instance.gen.ts | 5 - .../apiV2-class/requests/echo/post.gen.ts | 16 --- .../apiV2-class/requests/users/get.gen.ts | 16 --- .../requests/users/{username}/put.gen.ts | 17 --- .../generated/apiV2-class/types.gen.ts | 115 ------------------ packages/apicraft/src/test-runtime.ts | 3 - 21 files changed, 589 deletions(-) delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/index.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/index.ts delete mode 100644 packages/apicraft/generated/apiV2-class/instance.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts delete mode 100644 packages/apicraft/generated/apiV2-class/types.gen.ts delete mode 100644 packages/apicraft/src/test-runtime.ts diff --git a/packages/apicraft/apicraft.config.ts b/packages/apicraft/apicraft.config.ts index 2b58ac3..1d89ce0 100644 --- a/packages/apicraft/apicraft.config.ts +++ b/packages/apicraft/apicraft.config.ts @@ -12,14 +12,6 @@ const apicraftConfig = apicraft([ nameBy: 'path', groupBy: 'paths', plugins: ['tanstack'] - }, - { - input: 'example-apiV2.yaml', - output: 'generated/apiV2-class-runtime-instance', - instance: { name: 'axios', runtimeInstancePath: 'src/test-runtime' }, - nameBy: 'path', - groupBy: 'class', - plugins: ['tanstack'] } ]); diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts deleted file mode 100644 index fa0a80a..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/hooks.gen.ts +++ /dev/null @@ -1,85 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { useQuery, useMutation, queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import type { TanstackQuerySettings, TanstackMutationSettings, TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { instance } from "generated/apiV2-class-runtime-instance/instance.gen"; - -export const getUsersQueryKey = "getUsers"; - -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ - queryKey: ["getUsersQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params -}); - -export const getUsersMutationKey = "getUsers"; - -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["getUsersMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => instance.getUsers({ ...settings?.request, ...params }), - ...settings?.params -}); - -export const getUsersSuspenseQueryKey = "getUsers"; - -export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["getUsersSuspenseQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - queryFn: async () => instance.getUsers({ ...settings?.request }), - ...settings?.params -}); - -export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); - -export const putUserByUsernameQueryKey = "putUserByUsername"; - -export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["putUserByUsernameQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), - ...settings.params -}); - -export const putUserByUsernameMutationKey = "putUserByUsername"; - -export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["putUserByUsernameMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => instance.putUserByUsername({ ...settings?.request, ...params }), - ...settings?.params -}); - -export const putUserByUsernameSuspenseQueryKey = "putUserByUsername"; - -export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["putUserByUsernameSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => instance.putUserByUsername({ ...settings.request }), - ...settings.params -}); - -export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); - -export const postEchoQueryKey = "postEcho"; - -export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["postEchoQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => instance.postEcho({ ...settings.request }), - ...settings.params -}); - -export const postEchoMutationKey = "postEcho"; - -export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["postEchoMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => instance.postEcho({ ...settings?.request, ...params }), - ...settings?.params -}); - -export const postEchoSuspenseQueryKey = "postEcho"; - -export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["postEchoSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => instance.postEcho({ ...settings.request }), - ...settings.params -}); - -export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts deleted file mode 100644 index 724a162..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts -export * from './types.gen'; -export * from './hooks.gen'; -export * from './instance.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts deleted file mode 100644 index a8f51b7..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/instance.gen.ts +++ /dev/null @@ -1,49 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { AxiosRequestParams } from "@siberiacancode/apicraft"; - -import type { GetUserByNameData, GetUserByNameResponse, UpdateUserData, EchoData, EchoResponse } from "./types.gen"; - -import type { AxiosInstance } from "axios"; - -import { instance as runtimeInstance } from "../../src/test-runtime"; - -export type GetUsersRequestParams = AxiosRequestParams; - -export type PutUserByUsernameRequestParams = AxiosRequestParams; - -export type PostEchoRequestParams = AxiosRequestParams; - -export class ApiInstance { - private instance: AxiosInstance; - constructor() { - this.instance = runtimeInstance; - } - getUsers({ config, query }: GetUsersRequestParams = {}) { - return this.instance.request({ - method: "GET", - url: "/users", - params: query, - ...config - }); - } - putUserByUsername({ config, body, query, path }: PutUserByUsernameRequestParams) { - return this.instance.request({ - method: "PUT", - url: `/users/${path.username}`, - data: body, - params: query, - ...config - }); - } - postEcho({ config, body }: PostEchoRequestParams) { - return this.instance.request({ - method: "POST", - url: "/echo", - data: body, - ...config - }); - } -} - -export const instance = new ApiInstance(); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts b/packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts deleted file mode 100644 index bfb2c6e..0000000 --- a/packages/apicraft/generated/apiV2-class-runtime-instance/types.gen.ts +++ /dev/null @@ -1,115 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -/** - * User email address - */ -export type Email = string; - -export type User = { - /** - * User supplied username - */ - username?: string; - /** - * User first name - */ - firstName?: string; - /** - * User last name - */ - lastName?: string; - email?: Email; -}; - -export type GetUserByNameData = { - body?: never; - path?: never; - query?: { - /** - * Filter users without email - */ - with_email?: boolean; - }; - url: '/users'; -}; - -export type GetUserByNameErrors = { - /** - * Forbidden - */ - 403: unknown; - /** - * User not found - */ - 404: unknown; -}; - -export type GetUserByNameResponses = { - /** - * Success - */ - 200: User; -}; - -export type GetUserByNameResponse = GetUserByNameResponses[keyof GetUserByNameResponses]; - -export type UpdateUserData = { - /** - * Updated user object - */ - body: User; - path: { - /** - * The name that needs to be updated - */ - username: string; - }; - query?: { - /** - * Pretty print response - */ - pretty_print?: boolean; - }; - url: '/users/{username}'; -}; - -export type UpdateUserErrors = { - /** - * Invalid user supplied - */ - 400: unknown; - /** - * User not found - */ - 404: unknown; -}; - -export type UpdateUserResponses = { - /** - * OK - */ - 200: unknown; -}; - -export type EchoData = { - /** - * Echo payload - */ - body: string; - path?: never; - query?: never; - url: '/echo'; -}; - -export type EchoResponses = { - /** - * OK - */ - 200: string; -}; - -export type EchoResponse = EchoResponses[keyof EchoResponses]; - -export type ClientOptions = { - baseUrl: 'http://example.com/api/v1' | 'https://example.com/api/v1' | (string & {}); -}; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts deleted file mode 100644 index eee41a4..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoMutation.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { useMutation } from "@tanstack/react-query"; - -import { postEcho } from "../../requests/echo/post.gen"; - -export const postEchoMutationKey = "postEcho"; - -export const usePostEchoMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["postEchoMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => postEcho({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts deleted file mode 100644 index 36dbcd6..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { useQuery } from "@tanstack/react-query"; - -import { postEcho } from "../../requests/echo/post.gen"; - -export const postEchoQueryKey = "postEcho"; - -export const usePostEchoQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["postEchoQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => postEcho({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts deleted file mode 100644 index 1c1c4d9..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/echo/usePostEchoSuspenseQuery.gen.ts +++ /dev/null @@ -1,17 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import { postEcho } from "../../requests/echo/post.gen"; - -export const postEchoSuspenseQueryKey = "postEcho"; - -export const postEchoOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["postEchoSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => postEcho({ ...settings.request }), - ...settings.params -}); - -export const usePostEchoSuspenseQuery = (...args: Parameters) => useSuspenseQuery(postEchoOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts deleted file mode 100644 index 09e995e..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersMutation.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { useMutation } from "@tanstack/react-query"; - -import { getUsers } from "../../requests/users/get.gen"; - -export const getUsersMutationKey = "getUsers"; - -export const useGetUsersMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["getUsersMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => getUsers({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts deleted file mode 100644 index 69b5688..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { useQuery } from "@tanstack/react-query"; - -import { getUsers } from "../../requests/users/get.gen"; - -export const getUsersQueryKey = "getUsers"; - -export const useGetUsersQuery = (settings?: TanstackQuerySettings) => useQuery({ - queryKey: ["getUsersQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - queryFn: async () => getUsers({ ...settings?.request }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts deleted file mode 100644 index 39f6c6c..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/useGetUsersSuspenseQuery.gen.ts +++ /dev/null @@ -1,17 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import { getUsers } from "../../requests/users/get.gen"; - -export const getUsersSuspenseQueryKey = "getUsers"; - -export const getUsersOptions = (settings?: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["getUsersSuspenseQueryKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - queryFn: async () => getUsers({ ...settings?.request }), - ...settings?.params -}); - -export const useGetUsersSuspenseQuery = (...args: Parameters) => useSuspenseQuery(getUsersOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts deleted file mode 100644 index 9c43beb..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameMutation.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackMutationSettings } from "@siberiacancode/apicraft"; - -import { useMutation } from "@tanstack/react-query"; - -import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; - -export const putUserByUsernameMutationKey = "putUserByUsername"; - -export const usePutUserByUsernameMutation = (settings?: TanstackMutationSettings) => useMutation({ - mutationKey: ["putUserByUsernameMutationKey", settings?.request?.path, settings?.request?.query, settings?.request?.body], - mutationFn: async (params) => putUserByUsername({ ...settings?.request, ...params }), - ...settings?.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts deleted file mode 100644 index 0e64cde..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameQuery.gen.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackQuerySettings } from "@siberiacancode/apicraft"; - -import { useQuery } from "@tanstack/react-query"; - -import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; - -export const putUserByUsernameQueryKey = "putUserByUsername"; - -export const usePutUserByUsernameQuery = (settings: TanstackQuerySettings) => useQuery({ - queryKey: ["putUserByUsernameQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => putUserByUsername({ ...settings.request }), - ...settings.params -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts b/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts deleted file mode 100644 index 86f9129..0000000 --- a/packages/apicraft/generated/apiV2-class/hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen.ts +++ /dev/null @@ -1,17 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { TanstackSuspenseQuerySettings } from "@siberiacancode/apicraft"; - -import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; - -import { putUserByUsername } from "../../../requests/users/{username}/put.gen"; - -export const putUserByUsernameSuspenseQueryKey = "putUserByUsername"; - -export const putUserByUsernameOptions = (settings: TanstackSuspenseQuerySettings) => queryOptions({ - queryKey: ["putUserByUsernameSuspenseQueryKey", settings.request.path, settings.request.query, settings.request.body], - queryFn: async () => putUserByUsername({ ...settings.request }), - ...settings.params -}); - -export const usePutUserByUsernameSuspenseQuery = (...args: Parameters) => useSuspenseQuery(putUserByUsernameOptions(...args)); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/index.ts b/packages/apicraft/generated/apiV2-class/index.ts deleted file mode 100644 index 7db27e0..0000000 --- a/packages/apicraft/generated/apiV2-class/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts -export * from './types.gen'; -export * from './hooks/users/useGetUsersQuery.gen'; -export * from './hooks/users/useGetUsersSuspenseQuery.gen'; -export * from './hooks/users/useGetUsersMutation.gen'; -export * from './hooks/users/{username}/usePutUserByUsernameQuery.gen'; -export * from './hooks/users/{username}/usePutUserByUsernameSuspenseQuery.gen'; -export * from './hooks/users/{username}/usePutUserByUsernameMutation.gen'; -export * from './hooks/echo/usePostEchoQuery.gen'; -export * from './hooks/echo/usePostEchoSuspenseQuery.gen'; -export * from './hooks/echo/usePostEchoMutation.gen'; -export * from './instance.gen'; -export * from './requests/users/get.gen'; -export * from './requests/users/{username}/put.gen'; -export * from './requests/echo/post.gen'; \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/instance.gen.ts b/packages/apicraft/generated/apiV2-class/instance.gen.ts deleted file mode 100644 index c3838e0..0000000 --- a/packages/apicraft/generated/apiV2-class/instance.gen.ts +++ /dev/null @@ -1,5 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import axios from "axios"; - -export const instance = axios.create(); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts b/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts deleted file mode 100644 index 9311e68..0000000 --- a/packages/apicraft/generated/apiV2-class/requests/echo/post.gen.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { AxiosRequestParams } from "@siberiacancode/apicraft"; - -import type { EchoData, EchoResponse } from "../../types.gen"; - -import { instance } from "../../instance.gen"; - -export type PostEchoRequestParams = AxiosRequestParams; - -export const postEcho = ({ config, body }: PostEchoRequestParams) => instance.request({ - method: "POST", - url: "/echo", - data: body, - ...config -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts b/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts deleted file mode 100644 index f087f49..0000000 --- a/packages/apicraft/generated/apiV2-class/requests/users/get.gen.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { AxiosRequestParams } from "@siberiacancode/apicraft"; - -import type { GetUserByNameData, GetUserByNameResponse } from "../../types.gen"; - -import { instance } from "../../instance.gen"; - -export type GetUsersRequestParams = AxiosRequestParams; - -export const getUsers = ({ config, query }: GetUsersRequestParams = {}) => instance.request({ - method: "GET", - url: "/users", - params: query, - ...config -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts b/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts deleted file mode 100644 index 52ffe6a..0000000 --- a/packages/apicraft/generated/apiV2-class/requests/users/{username}/put.gen.ts +++ /dev/null @@ -1,17 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { AxiosRequestParams } from "@siberiacancode/apicraft"; - -import type { UpdateUserData } from "../../../types.gen"; - -import { instance } from "../../../instance.gen"; - -export type PutUserByUsernameRequestParams = AxiosRequestParams; - -export const putUserByUsername = ({ config, body, query, path }: PutUserByUsernameRequestParams) => instance.request({ - method: "PUT", - url: `/users/${path.username}`, - data: body, - params: query, - ...config -}); \ No newline at end of file diff --git a/packages/apicraft/generated/apiV2-class/types.gen.ts b/packages/apicraft/generated/apiV2-class/types.gen.ts deleted file mode 100644 index bfb2c6e..0000000 --- a/packages/apicraft/generated/apiV2-class/types.gen.ts +++ /dev/null @@ -1,115 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -/** - * User email address - */ -export type Email = string; - -export type User = { - /** - * User supplied username - */ - username?: string; - /** - * User first name - */ - firstName?: string; - /** - * User last name - */ - lastName?: string; - email?: Email; -}; - -export type GetUserByNameData = { - body?: never; - path?: never; - query?: { - /** - * Filter users without email - */ - with_email?: boolean; - }; - url: '/users'; -}; - -export type GetUserByNameErrors = { - /** - * Forbidden - */ - 403: unknown; - /** - * User not found - */ - 404: unknown; -}; - -export type GetUserByNameResponses = { - /** - * Success - */ - 200: User; -}; - -export type GetUserByNameResponse = GetUserByNameResponses[keyof GetUserByNameResponses]; - -export type UpdateUserData = { - /** - * Updated user object - */ - body: User; - path: { - /** - * The name that needs to be updated - */ - username: string; - }; - query?: { - /** - * Pretty print response - */ - pretty_print?: boolean; - }; - url: '/users/{username}'; -}; - -export type UpdateUserErrors = { - /** - * Invalid user supplied - */ - 400: unknown; - /** - * User not found - */ - 404: unknown; -}; - -export type UpdateUserResponses = { - /** - * OK - */ - 200: unknown; -}; - -export type EchoData = { - /** - * Echo payload - */ - body: string; - path?: never; - query?: never; - url: '/echo'; -}; - -export type EchoResponses = { - /** - * OK - */ - 200: string; -}; - -export type EchoResponse = EchoResponses[keyof EchoResponses]; - -export type ClientOptions = { - baseUrl: 'http://example.com/api/v1' | 'https://example.com/api/v1' | (string & {}); -}; \ No newline at end of file diff --git a/packages/apicraft/src/test-runtime.ts b/packages/apicraft/src/test-runtime.ts deleted file mode 100644 index 896817e..0000000 --- a/packages/apicraft/src/test-runtime.ts +++ /dev/null @@ -1,3 +0,0 @@ -import axios from 'axios'; - -export const instance = axios.create({}); From ed1df5bc02d9859909ce2d06b1a25a50927990bf Mon Sep 17 00:00:00 2001 From: vitrivdolkom Date: Sun, 1 Mar 2026 14:21:47 +0700 Subject: [PATCH 12/12] =?UTF-8?q?technical/apicraft-class=20=F0=9F=9A=80?= =?UTF-8?q?=20self=20review=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- .../tanstack/composed/helpers/generateMutationHookFile.ts | 2 +- .../tanstack/composed/helpers/generateQueryHookFile.ts | 3 ++- .../composed/helpers/generateSuspenseQueryHookFile.ts | 2 +- .../bin/plugins/tanstack/helpers/getMutationHook.ts | 2 ++ .../apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts | 6 ++++-- .../bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts | 8 +++++--- 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 5ff99b1..a3b3145 100644 --- a/.gitignore +++ b/.gitignore @@ -208,7 +208,7 @@ public gatsby-types.d.ts # Generated -!generated +generated # Turbo .turbo diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts index cf910e6..51ca5a2 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateMutationHookFile.ts @@ -14,7 +14,7 @@ import type { TanstackPluginConfig } from '../../types'; import { getMutationHook, getTanstackImport } from '../../helpers'; interface GenerateMutationHookFileParams { - plugin: Parameters['Handler']>[0]['plugin']; + plugin: DefinePlugin['Instance']; requestFilePath: string; requestName: string; } diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts index 8c9db29..a24b445 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateQueryHookFile.ts @@ -8,10 +8,11 @@ import { getImportInstance, getImportRequest } from '@/bin/plugins/helpers'; -import { getQueryHook, getTanstackImport } from '@/bin/plugins/tanstack/helpers'; import type { TanstackPlugin } from '../../types'; +import { getQueryHook, getTanstackImport } from '../../helpers'; + interface GenerateQueryHookParams { plugin: TanstackPlugin['Instance']; request: IR.OperationObject; diff --git a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts index 55bdf86..4c07b62 100644 --- a/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts +++ b/packages/apicraft/bin/plugins/tanstack/composed/helpers/generateSuspenseQueryHookFile.ts @@ -14,7 +14,7 @@ import type { TanstackPluginConfig } from '../../types'; import { getSuspenseQueryHook, getTanstackImport } from '../../helpers'; interface GenerateSuspenseQueryHookParams { - plugin: Parameters['Handler']>[0]['plugin']; + plugin: DefinePlugin['Instance']; request: IR.OperationObject; requestFilePath: string; requestName: string; diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts index b834696..0f84688 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getMutationHook.ts @@ -8,6 +8,7 @@ interface GetMutationHookParams { requestName: string; } +// export const requestNameMutationKey = requestName // const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation export const getMutationHook = ({ hookName, plugin, requestName }: GetMutationHookParams) => { // export const requestNameMutationKey = requestName; @@ -26,6 +27,7 @@ export const getMutationHook = ({ hookName, plugin, requestName }: GetMutationHo ) ); + // const useRequestNameMutation = (settings: TanstackMutationSettings) => useMutation const hookFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts index 1485adf..d0303a1 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getQueryHook.ts @@ -2,9 +2,9 @@ import type { IR } from '@hey-api/openapi-ts'; import ts from 'typescript'; -import type { TanstackPlugin } from '../types'; +import { getRequestInfo } from '@/bin/plugins/helpers/'; -import { getRequestInfo } from '../../helpers'; +import type { TanstackPlugin } from '../types'; interface GetQueryHookParams { hookName: string; @@ -13,6 +13,7 @@ interface GetQueryHookParams { requestName: string; } +// const requestNameQueryKey = requestName; // const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery export const getQueryHook = ({ hookName, request, plugin, requestName }: GetQueryHookParams) => { const requestInfo = getRequestInfo({ request }); @@ -33,6 +34,7 @@ export const getQueryHook = ({ hookName, request, plugin, requestName }: GetQuer ) ); + // const useRequestNameQuery = (settings: TanstackQuerySettings) => useQuery const hookFunction = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( diff --git a/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts index fc154dc..5670b22 100644 --- a/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts +++ b/packages/apicraft/bin/plugins/tanstack/helpers/getSuspenseQueryHook.ts @@ -2,9 +2,9 @@ import type { IR } from '@hey-api/openapi-ts'; import ts from 'typescript'; -import type { TanstackPlugin } from '../types'; +import { getRequestInfo } from '@/bin/plugins/helpers'; -import { getRequestInfo } from '../../helpers'; +import type { TanstackPlugin } from '../types'; interface GetSuspenseQueryHookParams { hookName: string; @@ -14,6 +14,8 @@ interface GetSuspenseQueryHookParams { requestName: string; } +// export const requestNameSuspenseQueryKey = requestName +// const requestNameOptions = queryOptions({...}) // const useRequestNameSuspenseQuery = (settings: TanstackSuspenseQuerySettings) => useSuspenseQuery export const getSuspenseQueryHook = ({ plugin, @@ -24,7 +26,7 @@ export const getSuspenseQueryHook = ({ }: GetSuspenseQueryHookParams) => { const requestInfo = getRequestInfo({ request }); - // export const requestNameSuspenseQueryKey = requestName; + // export const requestNameSuspenseQueryKey = requestName const suspenseQueryKey = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList(