Skip to content

Commit 19f6749

Browse files
authored
Merge pull request #1699 from hey-api/fix/sdk-meta-field
fix: allow passing arbitrary values to SDK functions via meta field
2 parents 5cd3d9e + 8ff188f commit 19f6749

File tree

100 files changed

+612
-103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+612
-103
lines changed

.changeset/four-rings-sniff.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix: allow passing arbitrary values to SDK functions via `meta` field

packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type ts from 'typescript';
33
import { compiler } from '../../../compiler';
44
import type { ObjectValue } from '../../../compiler/types';
55
import { clientApi, clientModulePath } from '../../../generate/client';
6-
import type { FileImportResult, TypeScriptFile } from '../../../generate/files';
6+
import type { TypeScriptFile } from '../../../generate/files';
77
import {
88
hasOperationDataRequired,
99
statusCodeToGroup,
@@ -26,6 +26,7 @@ import {
2626
importIdentifierResponse,
2727
} from '../typescript/ref';
2828
import { serviceFunctionIdentifier } from './plugin-legacy';
29+
import { createTypeOptions } from './typeOptions';
2930
import type { Config } from './types';
3031

3132
// copy-pasted from @hey-api/client-core
@@ -673,105 +674,6 @@ const generateFlatSdk = ({
673674
});
674675
};
675676

676-
const createTypeOptions = ({
677-
clientOptions,
678-
context,
679-
plugin,
680-
}: {
681-
clientOptions: FileImportResult;
682-
context: IR.Context;
683-
plugin: Plugin.Instance<Config>;
684-
}) => {
685-
const file = context.file({ id: sdkId })!;
686-
const client = getClientPlugin(context.config);
687-
const isNuxtClient = client.name === '@hey-api/client-nuxt';
688-
689-
const clientModule = clientModulePath({
690-
config: context.config,
691-
sourceOutput: file.nameWithoutExtension(),
692-
});
693-
const tDataShape = file.import({
694-
asType: true,
695-
module: clientModule,
696-
name: 'TDataShape',
697-
});
698-
const clientType = file.import({
699-
asType: true,
700-
module: clientModule,
701-
name: 'Client',
702-
});
703-
704-
const typeOptions = compiler.typeAliasDeclaration({
705-
exportType: true,
706-
name: 'Options',
707-
type: compiler.typeIntersectionNode({
708-
types: [
709-
compiler.typeReferenceNode({
710-
typeArguments: isNuxtClient
711-
? [
712-
compiler.typeReferenceNode({ typeName: 'TComposable' }),
713-
compiler.typeReferenceNode({ typeName: 'TData' }),
714-
]
715-
: [
716-
compiler.typeReferenceNode({ typeName: 'TData' }),
717-
compiler.typeReferenceNode({ typeName: 'ThrowOnError' }),
718-
],
719-
typeName: clientOptions.name,
720-
}),
721-
compiler.typeInterfaceNode({
722-
properties: [
723-
{
724-
comment: [
725-
'You can provide a client instance returned by `createClient()` instead of',
726-
'individual options. This might be also useful if you want to implement a',
727-
'custom client.',
728-
],
729-
isRequired: !plugin.client,
730-
name: 'client',
731-
type: compiler.typeReferenceNode({ typeName: clientType.name }),
732-
},
733-
],
734-
useLegacyResolution: false,
735-
}),
736-
],
737-
}),
738-
typeParameters: isNuxtClient
739-
? [
740-
compiler.typeParameterDeclaration({
741-
constraint: compiler.typeReferenceNode({ typeName: 'Composable' }),
742-
name: 'TComposable',
743-
}),
744-
compiler.typeParameterDeclaration({
745-
constraint: compiler.typeReferenceNode({
746-
typeName: tDataShape.name,
747-
}),
748-
defaultType: compiler.typeReferenceNode({
749-
typeName: tDataShape.name,
750-
}),
751-
name: 'TData',
752-
}),
753-
]
754-
: [
755-
compiler.typeParameterDeclaration({
756-
constraint: compiler.typeReferenceNode({
757-
typeName: tDataShape.name,
758-
}),
759-
defaultType: compiler.typeReferenceNode({
760-
typeName: tDataShape.name,
761-
}),
762-
name: 'TData',
763-
}),
764-
compiler.typeParameterDeclaration({
765-
constraint: compiler.keywordTypeNode({ keyword: 'boolean' }),
766-
defaultType: compiler.keywordTypeNode({ keyword: 'boolean' }),
767-
name: 'ThrowOnError',
768-
}),
769-
],
770-
});
771-
772-
file.add(typeOptions);
773-
};
774-
775677
export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
776678
const file = context.createFile({
777679
exportFromIndex: plugin.exportFromIndex,
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { compiler } from '../../../compiler';
2+
import { clientModulePath } from '../../../generate/client';
3+
import type { FileImportResult } from '../../../generate/files';
4+
import type { IR } from '../../../ir/types';
5+
import type { Plugin } from '../../types';
6+
import { getClientPlugin } from '../client-core/utils';
7+
import { sdkId } from './plugin';
8+
import type { Config } from './types';
9+
10+
export const createTypeOptions = ({
11+
clientOptions,
12+
context,
13+
plugin,
14+
}: {
15+
clientOptions: FileImportResult;
16+
context: IR.Context;
17+
plugin: Plugin.Instance<Config>;
18+
}) => {
19+
const file = context.file({ id: sdkId })!;
20+
const client = getClientPlugin(context.config);
21+
const isNuxtClient = client.name === '@hey-api/client-nuxt';
22+
23+
const clientModule = clientModulePath({
24+
config: context.config,
25+
sourceOutput: file.nameWithoutExtension(),
26+
});
27+
const tDataShape = file.import({
28+
asType: true,
29+
module: clientModule,
30+
name: 'TDataShape',
31+
});
32+
const clientType = file.import({
33+
asType: true,
34+
module: clientModule,
35+
name: 'Client',
36+
});
37+
38+
const typeOptions = compiler.typeAliasDeclaration({
39+
exportType: true,
40+
name: 'Options',
41+
type: compiler.typeIntersectionNode({
42+
types: [
43+
compiler.typeReferenceNode({
44+
typeArguments: isNuxtClient
45+
? [
46+
compiler.typeReferenceNode({ typeName: 'TComposable' }),
47+
compiler.typeReferenceNode({ typeName: 'TData' }),
48+
]
49+
: [
50+
compiler.typeReferenceNode({ typeName: 'TData' }),
51+
compiler.typeReferenceNode({ typeName: 'ThrowOnError' }),
52+
],
53+
typeName: clientOptions.name,
54+
}),
55+
compiler.typeInterfaceNode({
56+
properties: [
57+
{
58+
comment: [
59+
'You can provide a client instance returned by `createClient()` instead of',
60+
'individual options. This might be also useful if you want to implement a',
61+
'custom client.',
62+
],
63+
isRequired: !plugin.client,
64+
name: 'client',
65+
type: compiler.typeReferenceNode({ typeName: clientType.name }),
66+
},
67+
{
68+
comment: [
69+
'You can pass arbitrary values through the `meta` object. This can be',
70+
"used to access values that aren't defined as part of the SDK function.",
71+
],
72+
isRequired: false,
73+
name: 'meta',
74+
type: compiler.typeReferenceNode({
75+
typeArguments: [
76+
compiler.keywordTypeNode({ keyword: 'string' }),
77+
compiler.keywordTypeNode({ keyword: 'unknown' }),
78+
],
79+
typeName: 'Record',
80+
}),
81+
},
82+
],
83+
useLegacyResolution: false,
84+
}),
85+
],
86+
}),
87+
typeParameters: isNuxtClient
88+
? [
89+
compiler.typeParameterDeclaration({
90+
constraint: compiler.typeReferenceNode({ typeName: 'Composable' }),
91+
name: 'TComposable',
92+
}),
93+
compiler.typeParameterDeclaration({
94+
constraint: compiler.typeReferenceNode({
95+
typeName: tDataShape.name,
96+
}),
97+
defaultType: compiler.typeReferenceNode({
98+
typeName: tDataShape.name,
99+
}),
100+
name: 'TData',
101+
}),
102+
]
103+
: [
104+
compiler.typeParameterDeclaration({
105+
constraint: compiler.typeReferenceNode({
106+
typeName: tDataShape.name,
107+
}),
108+
defaultType: compiler.typeReferenceNode({
109+
typeName: tDataShape.name,
110+
}),
111+
name: 'TData',
112+
}),
113+
compiler.typeParameterDeclaration({
114+
constraint: compiler.keywordTypeNode({ keyword: 'boolean' }),
115+
defaultType: compiler.keywordTypeNode({ keyword: 'boolean' }),
116+
name: 'ThrowOnError',
117+
}),
118+
],
119+
});
120+
121+
file.add(typeOptions);
122+
};

packages/openapi-ts/test/__snapshots__/2.0.x/body-response-text-plain/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export const postFoo = <ThrowOnError extends boolean = false>(options: Options<PostFooData, ThrowOnError>) => {

packages/openapi-ts/test/__snapshots__/2.0.x/form-data/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export const postV1Foo = <ThrowOnError extends boolean = false>(options: Options<PostV1FooData, ThrowOnError>) => {

packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/sdk/default/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {

packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/sdk/throwOnError/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export const serviceWithEmptyTag = <ThrowOnError extends boolean = true>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {

packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1313
* custom client.
1414
*/
1515
client?: Client;
16+
/**
17+
* You can pass arbitrary values through the `meta` object. This can be
18+
* used to access values that aren't defined as part of the SDK function.
19+
*/
20+
meta?: Record<string, unknown>;
1621
};
1722

1823
export const postFoo = <ThrowOnError extends boolean = false>(options?: Options<PostFooData, ThrowOnError>) => {

packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@tanstack/angular-query-experimental/asClass/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export class DefaultService {

packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@tanstack/angular-query-experimental/axios/sdk.gen.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
1111
* custom client.
1212
*/
1313
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
1419
};
1520

1621
export const serviceWithEmptyTag = <ThrowOnError extends boolean = false>(options?: Options<ServiceWithEmptyTagData, ThrowOnError>) => {

0 commit comments

Comments
 (0)