Skip to content

Commit 5a9b6f6

Browse files
committed
fix(sdk): nested operationIds and tags. Add tests for nested class generation
1 parent 7c64fc8 commit 5a9b6f6

File tree

83 files changed

+9974
-4
lines changed

Some content is hidden

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

83 files changed

+9974
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
import type { ClientOptions } from './types.gen';
4+
import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client';
5+
6+
/**
7+
* The `createClientConfig()` function will be called on client initialization
8+
* and the returned object will become the client's initial configuration.
9+
*
10+
* You may want to initialize your client this way instead of calling
11+
* `setConfig()`. This is useful for example if you're using Next.js
12+
* to ensure your client always has the correct values.
13+
*/
14+
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
15+
16+
export const client = createClient(createConfig<ClientOptions>({
17+
baseUrl: 'https://api.example.com/v1'
18+
}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import type { Client, Config, ResolvedRequestOptions } from './types.gen';
2+
import {
3+
buildUrl,
4+
createConfig,
5+
createInterceptors,
6+
getParseAs,
7+
mergeConfigs,
8+
mergeHeaders,
9+
setAuthParams,
10+
} from './utils.gen';
11+
12+
type ReqInit = Omit<RequestInit, 'body' | 'headers'> & {
13+
body?: any;
14+
headers: ReturnType<typeof mergeHeaders>;
15+
};
16+
17+
export const createClient = (config: Config = {}): Client => {
18+
let _config = mergeConfigs(createConfig(), config);
19+
20+
const getConfig = (): Config => ({ ..._config });
21+
22+
const setConfig = (config: Config): Config => {
23+
_config = mergeConfigs(_config, config);
24+
return getConfig();
25+
};
26+
27+
const interceptors = createInterceptors<
28+
Request,
29+
Response,
30+
unknown,
31+
ResolvedRequestOptions
32+
>();
33+
34+
const request: Client['request'] = async (options) => {
35+
const opts = {
36+
..._config,
37+
...options,
38+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
39+
headers: mergeHeaders(_config.headers, options.headers),
40+
serializedBody: undefined,
41+
};
42+
43+
if (opts.security) {
44+
await setAuthParams({
45+
...opts,
46+
security: opts.security,
47+
});
48+
}
49+
50+
if (opts.requestValidator) {
51+
await opts.requestValidator(opts);
52+
}
53+
54+
if (opts.body && opts.bodySerializer) {
55+
opts.serializedBody = opts.bodySerializer(opts.body);
56+
}
57+
58+
// remove Content-Type header if body is empty to avoid sending invalid requests
59+
if (opts.serializedBody === undefined || opts.serializedBody === '') {
60+
opts.headers.delete('Content-Type');
61+
}
62+
63+
const url = buildUrl(opts);
64+
const requestInit: ReqInit = {
65+
redirect: 'follow',
66+
...opts,
67+
body: opts.serializedBody,
68+
};
69+
70+
let request = new Request(url, requestInit);
71+
72+
for (const fn of interceptors.request._fns) {
73+
if (fn) {
74+
request = await fn(request, opts);
75+
}
76+
}
77+
78+
// fetch must be assigned here, otherwise it would throw the error:
79+
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
80+
const _fetch = opts.fetch!;
81+
let response = await _fetch(request);
82+
83+
for (const fn of interceptors.response._fns) {
84+
if (fn) {
85+
response = await fn(response, request, opts);
86+
}
87+
}
88+
89+
const result = {
90+
request,
91+
response,
92+
};
93+
94+
if (response.ok) {
95+
if (
96+
response.status === 204 ||
97+
response.headers.get('Content-Length') === '0'
98+
) {
99+
return opts.responseStyle === 'data'
100+
? {}
101+
: {
102+
data: {},
103+
...result,
104+
};
105+
}
106+
107+
const parseAs =
108+
(opts.parseAs === 'auto'
109+
? getParseAs(response.headers.get('Content-Type'))
110+
: opts.parseAs) ?? 'json';
111+
112+
let data: any;
113+
switch (parseAs) {
114+
case 'arrayBuffer':
115+
case 'blob':
116+
case 'formData':
117+
case 'json':
118+
case 'text':
119+
data = await response[parseAs]();
120+
break;
121+
case 'stream':
122+
return opts.responseStyle === 'data'
123+
? response.body
124+
: {
125+
data: response.body,
126+
...result,
127+
};
128+
}
129+
130+
if (parseAs === 'json') {
131+
if (opts.responseValidator) {
132+
await opts.responseValidator(data);
133+
}
134+
135+
if (opts.responseTransformer) {
136+
data = await opts.responseTransformer(data);
137+
}
138+
}
139+
140+
return opts.responseStyle === 'data'
141+
? data
142+
: {
143+
data,
144+
...result,
145+
};
146+
}
147+
148+
const textError = await response.text();
149+
let jsonError: unknown;
150+
151+
try {
152+
jsonError = JSON.parse(textError);
153+
} catch {
154+
// noop
155+
}
156+
157+
const error = jsonError ?? textError;
158+
let finalError = error;
159+
160+
for (const fn of interceptors.error._fns) {
161+
if (fn) {
162+
finalError = (await fn(error, response, request, opts)) as string;
163+
}
164+
}
165+
166+
finalError = finalError || ({} as string);
167+
168+
if (opts.throwOnError) {
169+
throw finalError;
170+
}
171+
172+
// TODO: we probably want to return error and improve types
173+
return opts.responseStyle === 'data'
174+
? undefined
175+
: {
176+
error: finalError,
177+
...result,
178+
};
179+
};
180+
181+
return {
182+
buildUrl,
183+
connect: (options) => request({ ...options, method: 'CONNECT' }),
184+
delete: (options) => request({ ...options, method: 'DELETE' }),
185+
get: (options) => request({ ...options, method: 'GET' }),
186+
getConfig,
187+
head: (options) => request({ ...options, method: 'HEAD' }),
188+
interceptors,
189+
options: (options) => request({ ...options, method: 'OPTIONS' }),
190+
patch: (options) => request({ ...options, method: 'PATCH' }),
191+
post: (options) => request({ ...options, method: 'POST' }),
192+
put: (options) => request({ ...options, method: 'PUT' }),
193+
request,
194+
setConfig,
195+
trace: (options) => request({ ...options, method: 'TRACE' }),
196+
};
197+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export type { Auth } from '../core/auth.gen';
2+
export type { QuerySerializerOptions } from '../core/bodySerializer.gen';
3+
export {
4+
formDataBodySerializer,
5+
jsonBodySerializer,
6+
urlSearchParamsBodySerializer,
7+
} from '../core/bodySerializer.gen';
8+
export { buildClientParams } from '../core/params.gen';
9+
export { createClient } from './client.gen';
10+
export type {
11+
Client,
12+
ClientOptions,
13+
Config,
14+
CreateClientConfig,
15+
Options,
16+
OptionsLegacyParser,
17+
RequestOptions,
18+
RequestResult,
19+
ResolvedRequestOptions,
20+
ResponseStyle,
21+
TDataShape,
22+
} from './types.gen';
23+
export { createConfig, mergeHeaders } from './utils.gen';

0 commit comments

Comments
 (0)