diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts index 6ed457744..debe9a310 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts @@ -40,6 +40,7 @@ export const defaultConfig: Plugin.Config = { } }, asClass: false, + asInstance: false, auth: true, client: true, exportFromIndex: true, diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts index 20f972ec6..ef439c77d 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts @@ -488,6 +488,31 @@ const operationStatements = ({ name: 'client', }); + const thisClient = plugin.asInstance + ? compiler.propertyAccessExpression({ + expression: compiler.identifier({ text: 'this' }), + isOptional: false, + name: 'client', + }) + : undefined; + + let clientExpression; + if (heyApiClient?.name) { + clientExpression = compiler.binaryExpression({ + left: optionsClient, + operator: '??', + right: compiler.identifier({ text: heyApiClient.name }), + }); + } else if (thisClient) { + clientExpression = compiler.binaryExpression({ + left: optionsClient, + operator: '??', + right: thisClient, + }); + } else { + clientExpression = optionsClient; + } + return [ compiler.returnFunctionCall({ args: [ @@ -497,13 +522,7 @@ const operationStatements = ({ }), ], name: compiler.propertyAccessExpression({ - expression: heyApiClient?.name - ? compiler.binaryExpression({ - left: optionsClient, - operator: '??', - right: compiler.identifier({ text: heyApiClient.name }), - }) - : optionsClient, + expression: clientExpression, name: compiler.identifier({ text: operation.method }), }), types: isNuxtClient @@ -545,7 +564,7 @@ const generateClassSdk = ({ operation.summary && escapeComment(operation.summary), operation.description && escapeComment(operation.description), ], - isStatic: true, + isStatic: !plugin.asInstance, name: serviceFunctionIdentifier({ config: context.config, handleIllegal: false, @@ -618,6 +637,22 @@ const generateClassSdk = ({ context.subscribe('after', () => { for (const [name, nodes] of sdks) { + if (plugin.asInstance) { + nodes.unshift( + compiler.constructorDeclaration({ + multiLine: false, + parameters: [ + { + accessLevel: 'public', + isReadOnly: false, + name: 'client', + type: 'Client', + }, + ], + }), + ); + } + const node = compiler.classDeclaration({ decorator: undefined, members: nodes, diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/typeOptions.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/typeOptions.ts index 5bc20ace8..3d53cf128 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/typeOptions.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/typeOptions.ts @@ -63,7 +63,7 @@ export const createTypeOptions = ({ 'individual options. This might be also useful if you want to implement a', 'custom client.', ], - isRequired: !plugin.client, + isRequired: !plugin.client && !plugin.asInstance, name: 'client', type: compiler.typeReferenceNode({ typeName: clientType.name }), }, diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts index bc39044d7..e66abe070 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts @@ -19,6 +19,13 @@ export interface Config extends Plugin.Name<'@hey-api/sdk'> { * @default false */ asClass?: boolean; + /** + * SDK functions are non-static methods and the class must be instantiated + * with a client. + * + * @default false + */ + asInstance?: boolean; /** * Should the generated functions contain auth mechanisms? You may want to * disable this option if you're handling auth yourself or defining it