Skip to content

Commit

Permalink
Merge pull request #1699 from hey-api/fix/sdk-meta-field
Browse files Browse the repository at this point in the history
fix: allow passing arbitrary values to SDK functions via meta field
  • Loading branch information
mrlubos authored Feb 10, 2025
2 parents 5cd3d9e + 8ff188f commit 19f6749
Show file tree
Hide file tree
Showing 100 changed files with 612 additions and 103 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-rings-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

fix: allow passing arbitrary values to SDK functions via `meta` field
102 changes: 2 additions & 100 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type ts from 'typescript';
import { compiler } from '../../../compiler';
import type { ObjectValue } from '../../../compiler/types';
import { clientApi, clientModulePath } from '../../../generate/client';
import type { FileImportResult, TypeScriptFile } from '../../../generate/files';
import type { TypeScriptFile } from '../../../generate/files';
import {
hasOperationDataRequired,
statusCodeToGroup,
Expand All @@ -26,6 +26,7 @@ import {
importIdentifierResponse,
} from '../typescript/ref';
import { serviceFunctionIdentifier } from './plugin-legacy';
import { createTypeOptions } from './typeOptions';
import type { Config } from './types';

// copy-pasted from @hey-api/client-core
Expand Down Expand Up @@ -673,105 +674,6 @@ const generateFlatSdk = ({
});
};

const createTypeOptions = ({
clientOptions,
context,
plugin,
}: {
clientOptions: FileImportResult;
context: IR.Context;
plugin: Plugin.Instance<Config>;
}) => {
const file = context.file({ id: sdkId })!;
const client = getClientPlugin(context.config);
const isNuxtClient = client.name === '@hey-api/client-nuxt';

const clientModule = clientModulePath({
config: context.config,
sourceOutput: file.nameWithoutExtension(),
});
const tDataShape = file.import({
asType: true,
module: clientModule,
name: 'TDataShape',
});
const clientType = file.import({
asType: true,
module: clientModule,
name: 'Client',
});

const typeOptions = compiler.typeAliasDeclaration({
exportType: true,
name: 'Options',
type: compiler.typeIntersectionNode({
types: [
compiler.typeReferenceNode({
typeArguments: isNuxtClient
? [
compiler.typeReferenceNode({ typeName: 'TComposable' }),
compiler.typeReferenceNode({ typeName: 'TData' }),
]
: [
compiler.typeReferenceNode({ typeName: 'TData' }),
compiler.typeReferenceNode({ typeName: 'ThrowOnError' }),
],
typeName: clientOptions.name,
}),
compiler.typeInterfaceNode({
properties: [
{
comment: [
'You can provide a client instance returned by `createClient()` instead of',
'individual options. This might be also useful if you want to implement a',
'custom client.',
],
isRequired: !plugin.client,
name: 'client',
type: compiler.typeReferenceNode({ typeName: clientType.name }),
},
],
useLegacyResolution: false,
}),
],
}),
typeParameters: isNuxtClient
? [
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({ typeName: 'Composable' }),
name: 'TComposable',
}),
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
defaultType: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
name: 'TData',
}),
]
: [
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
defaultType: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
name: 'TData',
}),
compiler.typeParameterDeclaration({
constraint: compiler.keywordTypeNode({ keyword: 'boolean' }),
defaultType: compiler.keywordTypeNode({ keyword: 'boolean' }),
name: 'ThrowOnError',
}),
],
});

file.add(typeOptions);
};

export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
const file = context.createFile({
exportFromIndex: plugin.exportFromIndex,
Expand Down
122 changes: 122 additions & 0 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/typeOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { compiler } from '../../../compiler';
import { clientModulePath } from '../../../generate/client';
import type { FileImportResult } from '../../../generate/files';
import type { IR } from '../../../ir/types';
import type { Plugin } from '../../types';
import { getClientPlugin } from '../client-core/utils';
import { sdkId } from './plugin';
import type { Config } from './types';

export const createTypeOptions = ({
clientOptions,
context,
plugin,
}: {
clientOptions: FileImportResult;
context: IR.Context;
plugin: Plugin.Instance<Config>;
}) => {
const file = context.file({ id: sdkId })!;
const client = getClientPlugin(context.config);
const isNuxtClient = client.name === '@hey-api/client-nuxt';

const clientModule = clientModulePath({
config: context.config,
sourceOutput: file.nameWithoutExtension(),
});
const tDataShape = file.import({
asType: true,
module: clientModule,
name: 'TDataShape',
});
const clientType = file.import({
asType: true,
module: clientModule,
name: 'Client',
});

const typeOptions = compiler.typeAliasDeclaration({
exportType: true,
name: 'Options',
type: compiler.typeIntersectionNode({
types: [
compiler.typeReferenceNode({
typeArguments: isNuxtClient
? [
compiler.typeReferenceNode({ typeName: 'TComposable' }),
compiler.typeReferenceNode({ typeName: 'TData' }),
]
: [
compiler.typeReferenceNode({ typeName: 'TData' }),
compiler.typeReferenceNode({ typeName: 'ThrowOnError' }),
],
typeName: clientOptions.name,
}),
compiler.typeInterfaceNode({
properties: [
{
comment: [
'You can provide a client instance returned by `createClient()` instead of',
'individual options. This might be also useful if you want to implement a',
'custom client.',
],
isRequired: !plugin.client,
name: 'client',
type: compiler.typeReferenceNode({ typeName: clientType.name }),
},
{
comment: [
'You can pass arbitrary values through the `meta` object. This can be',
"used to access values that aren't defined as part of the SDK function.",
],
isRequired: false,
name: 'meta',
type: compiler.typeReferenceNode({
typeArguments: [
compiler.keywordTypeNode({ keyword: 'string' }),
compiler.keywordTypeNode({ keyword: 'unknown' }),
],
typeName: 'Record',
}),
},
],
useLegacyResolution: false,
}),
],
}),
typeParameters: isNuxtClient
? [
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({ typeName: 'Composable' }),
name: 'TComposable',
}),
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
defaultType: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
name: 'TData',
}),
]
: [
compiler.typeParameterDeclaration({
constraint: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
defaultType: compiler.typeReferenceNode({
typeName: tDataShape.name,
}),
name: 'TData',
}),
compiler.typeParameterDeclaration({
constraint: compiler.keywordTypeNode({ keyword: 'boolean' }),
defaultType: compiler.keywordTypeNode({ keyword: 'boolean' }),
name: 'ThrowOnError',
}),
],
});

file.add(typeOptions);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const postFoo = <ThrowOnError extends boolean = false>(options: Options<PostFooData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const postV1Foo = <ThrowOnError extends boolean = false>(options: Options<PostV1FooData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = true>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const postFoo = <ThrowOnError extends boolean = false>(options?: Options<PostFooData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export class DefaultService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export class DefaultService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};

export class DefaultService {
Expand Down
Loading

0 comments on commit 19f6749

Please sign in to comment.