@hey-api/openapi-ts 0.72.2 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +5 -12
  2. package/dist/chunk-QUDCWAFW.js +39 -0
  3. package/dist/chunk-QUDCWAFW.js.map +1 -0
  4. package/dist/clients/axios/client.ts +111 -0
  5. package/dist/clients/axios/index.ts +21 -0
  6. package/dist/clients/axios/types.ts +178 -0
  7. package/dist/clients/axios/utils.ts +286 -0
  8. package/dist/clients/core/auth.ts +40 -0
  9. package/dist/clients/core/bodySerializer.ts +84 -0
  10. package/dist/clients/core/params.ts +141 -0
  11. package/dist/clients/core/pathSerializer.ts +179 -0
  12. package/dist/clients/core/types.ts +98 -0
  13. package/dist/clients/fetch/client.ts +181 -0
  14. package/dist/clients/fetch/index.ts +22 -0
  15. package/dist/clients/fetch/types.ts +215 -0
  16. package/dist/clients/fetch/utils.ts +415 -0
  17. package/dist/clients/next/client.ts +163 -0
  18. package/dist/clients/next/index.ts +21 -0
  19. package/dist/clients/next/types.ts +166 -0
  20. package/dist/clients/next/utils.ts +404 -0
  21. package/dist/clients/nuxt/client.ts +145 -0
  22. package/dist/clients/nuxt/index.ts +22 -0
  23. package/dist/clients/nuxt/types.ts +192 -0
  24. package/dist/clients/nuxt/utils.ts +358 -0
  25. package/dist/index.cjs +63 -63
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +6 -4
  28. package/dist/index.d.ts +6 -4
  29. package/dist/index.js +9 -9
  30. package/dist/index.js.map +1 -1
  31. package/dist/internal.cjs +10 -10
  32. package/dist/internal.cjs.map +1 -1
  33. package/dist/internal.d.cts +2 -2
  34. package/dist/internal.d.ts +2 -2
  35. package/dist/internal.js +1 -1
  36. package/dist/{types.d-DtkupL5A.d.cts → types.d-CAqtwzfv.d.cts} +16 -25
  37. package/dist/{types.d-DtkupL5A.d.ts → types.d-CAqtwzfv.d.ts} +16 -25
  38. package/package.json +4 -3
  39. package/dist/chunk-LC3ZVK3Y.js +0 -39
  40. package/dist/chunk-LC3ZVK3Y.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ import type { AxiosError, RawAxiosRequestHeaders } from 'axios';
2
+ import axios from 'axios';
3
+
4
+ import type { Client, Config } from './types';
5
+ import {
6
+ buildUrl,
7
+ createConfig,
8
+ mergeConfigs,
9
+ mergeHeaders,
10
+ setAuthParams,
11
+ } from './utils';
12
+
13
+ export const createClient = (config: Config = {}): Client => {
14
+ let _config = mergeConfigs(createConfig(), config);
15
+
16
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
+ const { auth, ...configWithoutAuth } = _config;
18
+ const instance = axios.create(configWithoutAuth);
19
+
20
+ const getConfig = (): Config => ({ ..._config });
21
+
22
+ const setConfig = (config: Config): Config => {
23
+ _config = mergeConfigs(_config, config);
24
+ instance.defaults = {
25
+ ...instance.defaults,
26
+ ..._config,
27
+ // @ts-expect-error
28
+ headers: mergeHeaders(instance.defaults.headers, _config.headers),
29
+ };
30
+ return getConfig();
31
+ };
32
+
33
+ // @ts-expect-error
34
+ const request: Client['request'] = async (options) => {
35
+ const opts = {
36
+ ..._config,
37
+ ...options,
38
+ axios: options.axios ?? _config.axios ?? instance,
39
+ headers: mergeHeaders(_config.headers, options.headers),
40
+ };
41
+
42
+ if (opts.security) {
43
+ await setAuthParams({
44
+ ...opts,
45
+ security: opts.security,
46
+ });
47
+ }
48
+
49
+ if (opts.body && opts.bodySerializer) {
50
+ opts.body = opts.bodySerializer(opts.body);
51
+ }
52
+
53
+ const url = buildUrl(opts);
54
+
55
+ try {
56
+ // assign Axios here for consistency with fetch
57
+ const _axios = opts.axios!;
58
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
59
+ const { auth, ...optsWithoutAuth } = opts;
60
+ const response = await _axios({
61
+ ...optsWithoutAuth,
62
+ baseURL: opts.baseURL as string,
63
+ data: opts.body,
64
+ headers: opts.headers as RawAxiosRequestHeaders,
65
+ // let `paramsSerializer()` handle query params if it exists
66
+ params: opts.paramsSerializer ? opts.query : undefined,
67
+ url,
68
+ });
69
+
70
+ let { data } = response;
71
+
72
+ if (opts.responseType === 'json') {
73
+ if (opts.responseValidator) {
74
+ await opts.responseValidator(data);
75
+ }
76
+
77
+ if (opts.responseTransformer) {
78
+ data = await opts.responseTransformer(data);
79
+ }
80
+ }
81
+
82
+ return {
83
+ ...response,
84
+ data: data ?? {},
85
+ };
86
+ } catch (error) {
87
+ const e = error as AxiosError;
88
+ if (opts.throwOnError) {
89
+ throw e;
90
+ }
91
+ // @ts-expect-error
92
+ e.error = e.response?.data ?? {};
93
+ return e;
94
+ }
95
+ };
96
+
97
+ return {
98
+ buildUrl,
99
+ delete: (options) => request({ ...options, method: 'DELETE' }),
100
+ get: (options) => request({ ...options, method: 'GET' }),
101
+ getConfig,
102
+ head: (options) => request({ ...options, method: 'HEAD' }),
103
+ instance,
104
+ options: (options) => request({ ...options, method: 'OPTIONS' }),
105
+ patch: (options) => request({ ...options, method: 'PATCH' }),
106
+ post: (options) => request({ ...options, method: 'POST' }),
107
+ put: (options) => request({ ...options, method: 'PUT' }),
108
+ request,
109
+ setConfig,
110
+ } as Client;
111
+ };
@@ -0,0 +1,21 @@
1
+ export type { Auth } from '../core/auth';
2
+ export type { QuerySerializerOptions } from '../core/bodySerializer';
3
+ export {
4
+ formDataBodySerializer,
5
+ jsonBodySerializer,
6
+ urlSearchParamsBodySerializer,
7
+ } from '../core/bodySerializer';
8
+ export { buildClientParams } from '../core/params';
9
+ export { createClient } from './client';
10
+ export type {
11
+ Client,
12
+ ClientOptions,
13
+ Config,
14
+ CreateClientConfig,
15
+ Options,
16
+ OptionsLegacyParser,
17
+ RequestOptions,
18
+ RequestResult,
19
+ TDataShape,
20
+ } from './types';
21
+ export { createConfig } from './utils';
@@ -0,0 +1,178 @@
1
+ import type {
2
+ AxiosError,
3
+ AxiosInstance,
4
+ AxiosResponse,
5
+ AxiosStatic,
6
+ CreateAxiosDefaults,
7
+ } from 'axios';
8
+
9
+ import type { Auth } from '../core/auth';
10
+ import type {
11
+ Client as CoreClient,
12
+ Config as CoreConfig,
13
+ } from '../core/types';
14
+
15
+ export interface Config<T extends ClientOptions = ClientOptions>
16
+ extends Omit<CreateAxiosDefaults, 'auth' | 'baseURL' | 'headers' | 'method'>,
17
+ CoreConfig {
18
+ /**
19
+ * Axios implementation. You can use this option to provide a custom
20
+ * Axios instance.
21
+ *
22
+ * @default axios
23
+ */
24
+ axios?: AxiosStatic;
25
+ /**
26
+ * Base URL for all requests made by this client.
27
+ */
28
+ baseURL?: T['baseURL'];
29
+ /**
30
+ * An object containing any HTTP headers that you want to pre-populate your
31
+ * `Headers` object with.
32
+ *
33
+ * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
34
+ */
35
+ headers?:
36
+ | CreateAxiosDefaults['headers']
37
+ | Record<
38
+ string,
39
+ | string
40
+ | number
41
+ | boolean
42
+ | (string | number | boolean)[]
43
+ | null
44
+ | undefined
45
+ | unknown
46
+ >;
47
+ /**
48
+ * Throw an error instead of returning it in the response?
49
+ *
50
+ * @default false
51
+ */
52
+ throwOnError?: T['throwOnError'];
53
+ }
54
+
55
+ export interface RequestOptions<
56
+ ThrowOnError extends boolean = boolean,
57
+ Url extends string = string,
58
+ > extends Config<{
59
+ throwOnError: ThrowOnError;
60
+ }> {
61
+ /**
62
+ * Any body that you want to add to your request.
63
+ *
64
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
65
+ */
66
+ body?: unknown;
67
+ path?: Record<string, unknown>;
68
+ query?: Record<string, unknown>;
69
+ /**
70
+ * Security mechanism(s) to use for the request.
71
+ */
72
+ security?: ReadonlyArray<Auth>;
73
+ url: Url;
74
+ }
75
+
76
+ export type RequestResult<
77
+ TData = unknown,
78
+ TError = unknown,
79
+ ThrowOnError extends boolean = boolean,
80
+ > = ThrowOnError extends true
81
+ ? Promise<
82
+ AxiosResponse<
83
+ TData extends Record<string, unknown> ? TData[keyof TData] : TData
84
+ >
85
+ >
86
+ : Promise<
87
+ | (AxiosResponse<
88
+ TData extends Record<string, unknown> ? TData[keyof TData] : TData
89
+ > & { error: undefined })
90
+ | (AxiosError<
91
+ TError extends Record<string, unknown> ? TError[keyof TError] : TError
92
+ > & {
93
+ data: undefined;
94
+ error: TError extends Record<string, unknown>
95
+ ? TError[keyof TError]
96
+ : TError;
97
+ })
98
+ >;
99
+
100
+ export interface ClientOptions {
101
+ baseURL?: string;
102
+ throwOnError?: boolean;
103
+ }
104
+
105
+ type MethodFn = <
106
+ TData = unknown,
107
+ TError = unknown,
108
+ ThrowOnError extends boolean = false,
109
+ >(
110
+ options: Omit<RequestOptions<ThrowOnError>, 'method'>,
111
+ ) => RequestResult<TData, TError, ThrowOnError>;
112
+
113
+ type RequestFn = <
114
+ TData = unknown,
115
+ TError = unknown,
116
+ ThrowOnError extends boolean = false,
117
+ >(
118
+ options: Omit<RequestOptions<ThrowOnError>, 'method'> &
119
+ Pick<Required<RequestOptions<ThrowOnError>>, 'method'>,
120
+ ) => RequestResult<TData, TError, ThrowOnError>;
121
+
122
+ type BuildUrlFn = <
123
+ TData extends {
124
+ body?: unknown;
125
+ path?: Record<string, unknown>;
126
+ query?: Record<string, unknown>;
127
+ url: string;
128
+ },
129
+ >(
130
+ options: Pick<TData, 'url'> & Omit<Options<TData>, 'axios'>,
131
+ ) => string;
132
+
133
+ export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn> & {
134
+ instance: AxiosInstance;
135
+ };
136
+
137
+ /**
138
+ * The `createClientConfig()` function will be called on client initialization
139
+ * and the returned object will become the client's initial configuration.
140
+ *
141
+ * You may want to initialize your client this way instead of calling
142
+ * `setConfig()`. This is useful for example if you're using Next.js
143
+ * to ensure your client always has the correct values.
144
+ */
145
+ export type CreateClientConfig<T extends ClientOptions = ClientOptions> = (
146
+ override?: Config<ClientOptions & T>,
147
+ ) => Config<Required<ClientOptions> & T>;
148
+
149
+ export interface TDataShape {
150
+ body?: unknown;
151
+ headers?: unknown;
152
+ path?: unknown;
153
+ query?: unknown;
154
+ url: string;
155
+ }
156
+
157
+ type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
158
+
159
+ export type Options<
160
+ TData extends TDataShape = TDataShape,
161
+ ThrowOnError extends boolean = boolean,
162
+ > = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> &
163
+ Omit<TData, 'url'>;
164
+
165
+ export type OptionsLegacyParser<
166
+ TData = unknown,
167
+ ThrowOnError extends boolean = boolean,
168
+ > = TData extends { body?: any }
169
+ ? TData extends { headers?: any }
170
+ ? OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'headers' | 'url'> & TData
171
+ : OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'url'> &
172
+ TData &
173
+ Pick<RequestOptions<ThrowOnError>, 'headers'>
174
+ : TData extends { headers?: any }
175
+ ? OmitKeys<RequestOptions<ThrowOnError>, 'headers' | 'url'> &
176
+ TData &
177
+ Pick<RequestOptions<ThrowOnError>, 'body'>
178
+ : OmitKeys<RequestOptions<ThrowOnError>, 'url'> & TData;
@@ -0,0 +1,286 @@
1
+ import { getAuthToken } from '../core/auth';
2
+ import type {
3
+ QuerySerializer,
4
+ QuerySerializerOptions,
5
+ } from '../core/bodySerializer';
6
+ import type { ArraySeparatorStyle } from '../core/pathSerializer';
7
+ import {
8
+ serializeArrayParam,
9
+ serializeObjectParam,
10
+ serializePrimitiveParam,
11
+ } from '../core/pathSerializer';
12
+ import type { Client, ClientOptions, Config, RequestOptions } from './types';
13
+
14
+ interface PathSerializer {
15
+ path: Record<string, unknown>;
16
+ url: string;
17
+ }
18
+
19
+ const PATH_PARAM_RE = /\{[^{}]+\}/g;
20
+
21
+ const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
22
+ let url = _url;
23
+ const matches = _url.match(PATH_PARAM_RE);
24
+ if (matches) {
25
+ for (const match of matches) {
26
+ let explode = false;
27
+ let name = match.substring(1, match.length - 1);
28
+ let style: ArraySeparatorStyle = 'simple';
29
+
30
+ if (name.endsWith('*')) {
31
+ explode = true;
32
+ name = name.substring(0, name.length - 1);
33
+ }
34
+
35
+ if (name.startsWith('.')) {
36
+ name = name.substring(1);
37
+ style = 'label';
38
+ } else if (name.startsWith(';')) {
39
+ name = name.substring(1);
40
+ style = 'matrix';
41
+ }
42
+
43
+ const value = path[name];
44
+
45
+ if (value === undefined || value === null) {
46
+ continue;
47
+ }
48
+
49
+ if (Array.isArray(value)) {
50
+ url = url.replace(
51
+ match,
52
+ serializeArrayParam({ explode, name, style, value }),
53
+ );
54
+ continue;
55
+ }
56
+
57
+ if (typeof value === 'object') {
58
+ url = url.replace(
59
+ match,
60
+ serializeObjectParam({
61
+ explode,
62
+ name,
63
+ style,
64
+ value: value as Record<string, unknown>,
65
+ valueOnly: true,
66
+ }),
67
+ );
68
+ continue;
69
+ }
70
+
71
+ if (style === 'matrix') {
72
+ url = url.replace(
73
+ match,
74
+ `;${serializePrimitiveParam({
75
+ name,
76
+ value: value as string,
77
+ })}`,
78
+ );
79
+ continue;
80
+ }
81
+
82
+ const replaceValue = encodeURIComponent(
83
+ style === 'label' ? `.${value as string}` : (value as string),
84
+ );
85
+ url = url.replace(match, replaceValue);
86
+ }
87
+ }
88
+ return url;
89
+ };
90
+
91
+ export const createQuerySerializer = <T = unknown>({
92
+ allowReserved,
93
+ array,
94
+ object,
95
+ }: QuerySerializerOptions = {}) => {
96
+ const querySerializer = (queryParams: T) => {
97
+ const search: string[] = [];
98
+ if (queryParams && typeof queryParams === 'object') {
99
+ for (const name in queryParams) {
100
+ const value = queryParams[name];
101
+
102
+ if (value === undefined || value === null) {
103
+ continue;
104
+ }
105
+
106
+ if (Array.isArray(value)) {
107
+ const serializedArray = serializeArrayParam({
108
+ allowReserved,
109
+ explode: true,
110
+ name,
111
+ style: 'form',
112
+ value,
113
+ ...array,
114
+ });
115
+ if (serializedArray) search.push(serializedArray);
116
+ } else if (typeof value === 'object') {
117
+ const serializedObject = serializeObjectParam({
118
+ allowReserved,
119
+ explode: true,
120
+ name,
121
+ style: 'deepObject',
122
+ value: value as Record<string, unknown>,
123
+ ...object,
124
+ });
125
+ if (serializedObject) search.push(serializedObject);
126
+ } else {
127
+ const serializedPrimitive = serializePrimitiveParam({
128
+ allowReserved,
129
+ name,
130
+ value: value as string,
131
+ });
132
+ if (serializedPrimitive) search.push(serializedPrimitive);
133
+ }
134
+ }
135
+ }
136
+ return search.join('&');
137
+ };
138
+ return querySerializer;
139
+ };
140
+
141
+ export const setAuthParams = async ({
142
+ security,
143
+ ...options
144
+ }: Pick<Required<RequestOptions>, 'security'> &
145
+ Pick<RequestOptions, 'auth' | 'query'> & {
146
+ headers: Record<any, unknown>;
147
+ }) => {
148
+ for (const auth of security) {
149
+ const token = await getAuthToken(auth, options.auth);
150
+
151
+ if (!token) {
152
+ continue;
153
+ }
154
+
155
+ const name = auth.name ?? 'Authorization';
156
+
157
+ switch (auth.in) {
158
+ case 'query':
159
+ if (!options.query) {
160
+ options.query = {};
161
+ }
162
+ options.query[name] = token;
163
+ break;
164
+ case 'cookie': {
165
+ const value = `${name}=${token}`;
166
+ if ('Cookie' in options.headers && options.headers['Cookie']) {
167
+ options.headers['Cookie'] = `${options.headers['Cookie']}; ${value}`;
168
+ } else {
169
+ options.headers['Cookie'] = value;
170
+ }
171
+ break;
172
+ }
173
+ case 'header':
174
+ default:
175
+ options.headers[name] = token;
176
+ break;
177
+ }
178
+
179
+ return;
180
+ }
181
+ };
182
+
183
+ export const buildUrl: Client['buildUrl'] = (options) => {
184
+ const url = getUrl({
185
+ path: options.path,
186
+ // let `paramsSerializer()` handle query params if it exists
187
+ query: !options.paramsSerializer ? options.query : undefined,
188
+ querySerializer:
189
+ typeof options.querySerializer === 'function'
190
+ ? options.querySerializer
191
+ : createQuerySerializer(options.querySerializer),
192
+ url: options.url,
193
+ });
194
+ return url;
195
+ };
196
+
197
+ export const getUrl = ({
198
+ path,
199
+ query,
200
+ querySerializer,
201
+ url: _url,
202
+ }: {
203
+ path?: Record<string, unknown>;
204
+ query?: Record<string, unknown>;
205
+ querySerializer: QuerySerializer;
206
+ url: string;
207
+ }) => {
208
+ const pathUrl = _url.startsWith('/') ? _url : `/${_url}`;
209
+ let url = pathUrl;
210
+ if (path) {
211
+ url = defaultPathSerializer({ path, url });
212
+ }
213
+ let search = query ? querySerializer(query) : '';
214
+ if (search.startsWith('?')) {
215
+ search = search.substring(1);
216
+ }
217
+ if (search) {
218
+ url += `?${search}`;
219
+ }
220
+ return url;
221
+ };
222
+
223
+ export const mergeConfigs = (a: Config, b: Config): Config => {
224
+ const config = { ...a, ...b };
225
+ config.headers = mergeHeaders(a.headers, b.headers);
226
+ return config;
227
+ };
228
+
229
+ /**
230
+ * Special Axios headers keywords allowing to set headers by request method.
231
+ */
232
+ export const axiosHeadersKeywords = [
233
+ 'common',
234
+ 'delete',
235
+ 'get',
236
+ 'head',
237
+ 'patch',
238
+ 'post',
239
+ 'put',
240
+ ] as const;
241
+
242
+ export const mergeHeaders = (
243
+ ...headers: Array<Required<Config>['headers'] | undefined>
244
+ ): Record<any, unknown> => {
245
+ const mergedHeaders: Record<any, unknown> = {};
246
+ for (const header of headers) {
247
+ if (!header || typeof header !== 'object') {
248
+ continue;
249
+ }
250
+
251
+ const iterator = Object.entries(header);
252
+
253
+ for (const [key, value] of iterator) {
254
+ if (
255
+ axiosHeadersKeywords.includes(
256
+ key as (typeof axiosHeadersKeywords)[number],
257
+ ) &&
258
+ typeof value === 'object'
259
+ ) {
260
+ mergedHeaders[key] = {
261
+ ...(mergedHeaders[key] as Record<any, unknown>),
262
+ ...value,
263
+ };
264
+ } else if (value === null) {
265
+ delete mergedHeaders[key];
266
+ } else if (Array.isArray(value)) {
267
+ for (const v of value) {
268
+ // @ts-expect-error
269
+ mergedHeaders[key] = [...(mergedHeaders[key] ?? []), v as string];
270
+ }
271
+ } else if (value !== undefined) {
272
+ // assume object headers are meant to be JSON stringified, i.e. their
273
+ // content value in OpenAPI specification is 'application/json'
274
+ mergedHeaders[key] =
275
+ typeof value === 'object' ? JSON.stringify(value) : (value as string);
276
+ }
277
+ }
278
+ }
279
+ return mergedHeaders;
280
+ };
281
+
282
+ export const createConfig = <T extends ClientOptions = ClientOptions>(
283
+ override: Config<Omit<ClientOptions, keyof T> & T> = {},
284
+ ): Config<Omit<ClientOptions, keyof T> & T> => ({
285
+ ...override,
286
+ });
@@ -0,0 +1,40 @@
1
+ export type AuthToken = string | undefined;
2
+
3
+ export interface Auth {
4
+ /**
5
+ * Which part of the request do we use to send the auth?
6
+ *
7
+ * @default 'header'
8
+ */
9
+ in?: 'header' | 'query' | 'cookie';
10
+ /**
11
+ * Header or query parameter name.
12
+ *
13
+ * @default 'Authorization'
14
+ */
15
+ name?: string;
16
+ scheme?: 'basic' | 'bearer';
17
+ type: 'apiKey' | 'http';
18
+ }
19
+
20
+ export const getAuthToken = async (
21
+ auth: Auth,
22
+ callback: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken,
23
+ ): Promise<string | undefined> => {
24
+ const token =
25
+ typeof callback === 'function' ? await callback(auth) : callback;
26
+
27
+ if (!token) {
28
+ return;
29
+ }
30
+
31
+ if (auth.scheme === 'bearer') {
32
+ return `Bearer ${token}`;
33
+ }
34
+
35
+ if (auth.scheme === 'basic') {
36
+ return `Basic ${btoa(token)}`;
37
+ }
38
+
39
+ return token;
40
+ };