@kollors/react-codegen 2.0.0-alpha.2 → 2.0.0-alpha.4
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.
- package/README.md +39 -1
- package/README.ru.md +39 -1
- package/dist/generate.js +6 -31
- package/dist/generate.js.map +1 -1
- package/dist/openapi/document.d.ts +15 -0
- package/dist/openapi/document.js +113 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/generate.d.ts +3 -0
- package/dist/openapi/generate.js +66 -0
- package/dist/openapi/generate.js.map +1 -0
- package/dist/openapi/names.d.ts +6 -0
- package/dist/openapi/names.js +24 -0
- package/dist/openapi/names.js.map +1 -0
- package/dist/openapi/operations.d.ts +11 -0
- package/dist/openapi/operations.js +328 -0
- package/dist/openapi/operations.js.map +1 -0
- package/dist/openapi/schema.d.ts +19 -0
- package/dist/openapi/schema.js +313 -0
- package/dist/openapi/schema.js.map +1 -0
- package/dist/openapi-fetcher.d.ts +3 -27
- package/dist/openapi-fetcher.js +2 -163
- package/dist/openapi-fetcher.js.map +1 -1
- package/dist/openapi-runtime.d.ts +45 -0
- package/dist/openapi-runtime.js +302 -0
- package/dist/openapi-runtime.js.map +1 -0
- package/dist/openapi-runtime.source +313 -0
- package/dist/types.d.ts +2 -7
- package/package.json +2 -3
- package/templates/graphql.template +1 -0
- package/templates/openapi.template +0 -45
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
function readConfiguredToken(auth) {
|
|
2
|
+
if (auth.storage === 'none')
|
|
3
|
+
return '';
|
|
4
|
+
if (auth.storage === 'cookie') {
|
|
5
|
+
if (typeof document === 'undefined' || !auth.key)
|
|
6
|
+
return '';
|
|
7
|
+
const cookie = document.cookie
|
|
8
|
+
.split(';')
|
|
9
|
+
.map((part) => part.trim())
|
|
10
|
+
.find((part) => part.startsWith(`${auth.key}=`));
|
|
11
|
+
if (!cookie)
|
|
12
|
+
return '';
|
|
13
|
+
const value = cookie.slice(auth.key.length + 1);
|
|
14
|
+
try {
|
|
15
|
+
return decodeURIComponent(value);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (typeof globalThis[auth.storage] === 'undefined' || !auth.key)
|
|
22
|
+
return '';
|
|
23
|
+
return globalThis[auth.storage].getItem(auth.key) ?? '';
|
|
24
|
+
}
|
|
25
|
+
function authorizationValue(configuration) {
|
|
26
|
+
if (configuration.getToken)
|
|
27
|
+
return configuration.getToken() ?? '';
|
|
28
|
+
const auth = configuration.auth;
|
|
29
|
+
if (!auth)
|
|
30
|
+
return '';
|
|
31
|
+
const token = readConfiguredToken(auth);
|
|
32
|
+
if (!token || auth.scheme === false)
|
|
33
|
+
return token;
|
|
34
|
+
const scheme = auth.scheme ?? 'Bearer';
|
|
35
|
+
if (!scheme)
|
|
36
|
+
return token;
|
|
37
|
+
return token.toLowerCase().startsWith(`${scheme.toLowerCase()} `) ? token : `${scheme} ${token}`;
|
|
38
|
+
}
|
|
39
|
+
function withBaseUrl(baseUrl, url) {
|
|
40
|
+
if (!baseUrl || /^[a-z][a-z\d+.-]*:\/\//i.test(url))
|
|
41
|
+
return url;
|
|
42
|
+
return `${baseUrl.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}`;
|
|
43
|
+
}
|
|
44
|
+
export class OpenapiHttpError extends Error {
|
|
45
|
+
status;
|
|
46
|
+
statusText;
|
|
47
|
+
url;
|
|
48
|
+
data;
|
|
49
|
+
constructor(status, statusText, url, data) {
|
|
50
|
+
super(`HTTP ${status}${statusText ? ` ${statusText}` : ''} for ${url}.`);
|
|
51
|
+
this.status = status;
|
|
52
|
+
this.statusText = statusText;
|
|
53
|
+
this.url = url;
|
|
54
|
+
this.data = data;
|
|
55
|
+
this.name = 'OpenapiHttpError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parameterScalar(value) {
|
|
59
|
+
if (value === null)
|
|
60
|
+
return '';
|
|
61
|
+
if (typeof value === 'object' || value === undefined)
|
|
62
|
+
throw new TypeError('OpenAPI parameters must contain scalar values.');
|
|
63
|
+
return String(value);
|
|
64
|
+
}
|
|
65
|
+
function parameterParts(value, explode, encode) {
|
|
66
|
+
if (Array.isArray(value))
|
|
67
|
+
return value.map((item) => encode(parameterScalar(item)));
|
|
68
|
+
if (value !== null && typeof value === 'object') {
|
|
69
|
+
return Object.entries(value).flatMap(([key, item]) => {
|
|
70
|
+
const pair = [encode(key), encode(parameterScalar(item))];
|
|
71
|
+
return explode ? [pair.join('=')] : pair;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return [encode(parameterScalar(value))];
|
|
75
|
+
}
|
|
76
|
+
function serializeQueryParams(queryParams, parameters = []) {
|
|
77
|
+
const result = [];
|
|
78
|
+
const append = (key, encodedValue) => {
|
|
79
|
+
result.push(`${encodeURIComponent(key)}=${encodedValue}`);
|
|
80
|
+
};
|
|
81
|
+
if (queryParams == null)
|
|
82
|
+
return '';
|
|
83
|
+
if (queryParams instanceof URLSearchParams)
|
|
84
|
+
return queryParams.toString();
|
|
85
|
+
if (typeof queryParams !== 'object' || Array.isArray(queryParams)) {
|
|
86
|
+
throw new TypeError('OpenAPI query parameters must be an object.');
|
|
87
|
+
}
|
|
88
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
89
|
+
if (value === undefined)
|
|
90
|
+
continue;
|
|
91
|
+
const parameter = parameters.find((item) => item.in === 'query' && item.name === key);
|
|
92
|
+
const style = parameter?.style ?? 'form';
|
|
93
|
+
const explode = parameter?.explode ?? true;
|
|
94
|
+
if (style === 'deepObject') {
|
|
95
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
96
|
+
throw new TypeError(`deepObject requires an object: ${key}`);
|
|
97
|
+
for (const [name, item] of Object.entries(value))
|
|
98
|
+
append(`${key}[${name}]`, encodeURIComponent(parameterScalar(item)));
|
|
99
|
+
}
|
|
100
|
+
else if (style === 'form' && explode && value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
101
|
+
for (const [name, item] of Object.entries(value))
|
|
102
|
+
append(name, encodeURIComponent(parameterScalar(item)));
|
|
103
|
+
}
|
|
104
|
+
else if (explode && Array.isArray(value)) {
|
|
105
|
+
for (const item of value)
|
|
106
|
+
append(key, encodeURIComponent(parameterScalar(item)));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const separator = style === 'spaceDelimited' ? '%20' : style === 'pipeDelimited' ? '|' : ',';
|
|
110
|
+
append(key, parameterParts(value, false, encodeURIComponent).join(separator));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return result.join('&');
|
|
114
|
+
}
|
|
115
|
+
function isJsonContentType(contentType) {
|
|
116
|
+
const mime = contentType.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
117
|
+
return mime === 'application/json' || /^application\/[^/;\s]+\+json$/.test(mime);
|
|
118
|
+
}
|
|
119
|
+
function requestBody(body, contentType) {
|
|
120
|
+
if (body === undefined)
|
|
121
|
+
return undefined;
|
|
122
|
+
if (body instanceof FormData || body instanceof Blob || body instanceof URLSearchParams)
|
|
123
|
+
return body;
|
|
124
|
+
if (isJsonContentType(contentType))
|
|
125
|
+
return JSON.stringify(body);
|
|
126
|
+
if (contentType === 'multipart/form-data' || contentType === 'application/x-www-form-urlencoded') {
|
|
127
|
+
if (body === null || typeof body !== 'object' || Array.isArray(body))
|
|
128
|
+
throw new TypeError(`${contentType} requires an object body.`);
|
|
129
|
+
const form = new FormData();
|
|
130
|
+
for (const [key, value] of Object.entries(body)) {
|
|
131
|
+
if (value === undefined)
|
|
132
|
+
continue;
|
|
133
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
134
|
+
if (item instanceof Blob)
|
|
135
|
+
form.append(key, item);
|
|
136
|
+
else if (item !== null && typeof item === 'object') {
|
|
137
|
+
const json = JSON.stringify(item);
|
|
138
|
+
form.append(key, contentType === 'multipart/form-data' ? new Blob([json], { type: 'application/json' }) : json);
|
|
139
|
+
}
|
|
140
|
+
else
|
|
141
|
+
form.append(key, parameterScalar(item));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (contentType === 'multipart/form-data')
|
|
145
|
+
return form;
|
|
146
|
+
const params = new URLSearchParams();
|
|
147
|
+
form.forEach((value, key) => {
|
|
148
|
+
if (typeof value !== 'string')
|
|
149
|
+
throw new TypeError('URL-encoded bodies cannot contain binary files.');
|
|
150
|
+
params.append(key, value);
|
|
151
|
+
});
|
|
152
|
+
return params;
|
|
153
|
+
}
|
|
154
|
+
if (typeof body === 'string')
|
|
155
|
+
return body;
|
|
156
|
+
throw new TypeError(`Unsupported request body for content type ${contentType}.`);
|
|
157
|
+
}
|
|
158
|
+
function requestHeaders(value, parameters) {
|
|
159
|
+
if (value instanceof Headers || Array.isArray(value))
|
|
160
|
+
return new Headers(value);
|
|
161
|
+
const headers = new Headers();
|
|
162
|
+
if (value && typeof value === 'object') {
|
|
163
|
+
for (const [key, item] of Object.entries(value)) {
|
|
164
|
+
if (item === undefined)
|
|
165
|
+
continue;
|
|
166
|
+
const parameter = parameters.find((entry) => entry.in === 'header' && entry.name.toLowerCase() === key.toLowerCase());
|
|
167
|
+
headers.set(key, parameterParts(item, parameter?.explode ?? false, (part) => part).join(','));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return headers;
|
|
171
|
+
}
|
|
172
|
+
function withQueryParams(url, serialized) {
|
|
173
|
+
if (!serialized)
|
|
174
|
+
return url;
|
|
175
|
+
const hashIndex = url.indexOf('#');
|
|
176
|
+
const base = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
177
|
+
const hash = hashIndex === -1 ? '' : url.slice(hashIndex);
|
|
178
|
+
const separator = base.includes('?') ? (base.endsWith('?') || base.endsWith('&') ? '' : '&') : '?';
|
|
179
|
+
return `${base}${separator}${serialized}${hash}`;
|
|
180
|
+
}
|
|
181
|
+
async function readResponse(response, responseType) {
|
|
182
|
+
if (response.status === 204 || response.status === 205)
|
|
183
|
+
return undefined;
|
|
184
|
+
if (responseType === 'blob')
|
|
185
|
+
return await response.blob();
|
|
186
|
+
const contentType = response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
187
|
+
const json = isJsonContentType(contentType);
|
|
188
|
+
if (contentType.startsWith('text/') || (!json && contentType.includes('xml')))
|
|
189
|
+
return await response.text();
|
|
190
|
+
if (response.body === null || response.headers.get('content-length') === '0')
|
|
191
|
+
return undefined;
|
|
192
|
+
if (json)
|
|
193
|
+
return await response.json();
|
|
194
|
+
return await response.blob();
|
|
195
|
+
}
|
|
196
|
+
export function createOpenapiFetcher(configuration = {}) {
|
|
197
|
+
return async function openapiFetcher(options) {
|
|
198
|
+
try {
|
|
199
|
+
const parameters = options.parameters ?? [];
|
|
200
|
+
const headers = new Headers();
|
|
201
|
+
const contentType = options.contentType ?? 'application/json';
|
|
202
|
+
if (options.body !== undefined) {
|
|
203
|
+
if (contentType === '*/*') {
|
|
204
|
+
if (!(options.body instanceof Blob))
|
|
205
|
+
throw new TypeError('Wildcard request content requires a Blob body.');
|
|
206
|
+
headers.set('content-type', options.body.type || 'application/octet-stream');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
headers.set('content-type', contentType);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (options.accept)
|
|
213
|
+
headers.set('accept', options.accept);
|
|
214
|
+
const token = authorizationValue(configuration);
|
|
215
|
+
if (token)
|
|
216
|
+
headers.set('authorization', token);
|
|
217
|
+
requestHeaders(options.headers, parameters).forEach((value, key) => {
|
|
218
|
+
headers.set(key, value);
|
|
219
|
+
});
|
|
220
|
+
const body = requestBody(options.body, headers.get('content-type') ?? contentType);
|
|
221
|
+
if (body instanceof FormData)
|
|
222
|
+
headers.delete('content-type');
|
|
223
|
+
for (const parameter of parameters) {
|
|
224
|
+
if (!parameter.required || parameter.in === 'path')
|
|
225
|
+
continue;
|
|
226
|
+
const value = parameter.in === 'header'
|
|
227
|
+
? headers.get(parameter.name)
|
|
228
|
+
: options.queryParams?.[parameter.name];
|
|
229
|
+
if (value === undefined || (parameter.in === 'header' && value === null))
|
|
230
|
+
throw new Error(`Missing required OpenAPI ${parameter.in} parameter "${parameter.name}" for ${options.url}.`);
|
|
231
|
+
}
|
|
232
|
+
const pathParams = options.pathParams;
|
|
233
|
+
const path = options.url.replace(/\{([^}]+)}/g, (_match, key) => {
|
|
234
|
+
const value = pathParams?.[key];
|
|
235
|
+
if (value === undefined || value === null)
|
|
236
|
+
throw new Error(`Missing required OpenAPI path parameter "${key}" for ${options.url}.`);
|
|
237
|
+
const parameter = parameters.find((item) => item.in === 'path' && item.name === key);
|
|
238
|
+
return parameterParts(value, parameter?.explode ?? false, encodeURIComponent).join(',');
|
|
239
|
+
});
|
|
240
|
+
const pathSegments = path.split(/[?#]/, 1)[0]?.split('/') ?? [];
|
|
241
|
+
if (pathSegments.some((segment) => /^(?:\.|%2e){1,2}$/i.test(segment))) {
|
|
242
|
+
throw new Error(`OpenAPI path contains a dot segment that Fetch would normalize: ${options.url}.`);
|
|
243
|
+
}
|
|
244
|
+
const url = withBaseUrl(configuration.baseUrl, path);
|
|
245
|
+
const queryParams = serializeQueryParams(options.queryParams, parameters);
|
|
246
|
+
const requestUrl = withQueryParams(url, queryParams);
|
|
247
|
+
let response;
|
|
248
|
+
try {
|
|
249
|
+
response = await fetch(requestUrl, {
|
|
250
|
+
...(body === undefined ? {} : { body }),
|
|
251
|
+
headers,
|
|
252
|
+
method: options.method.toUpperCase(),
|
|
253
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
254
|
+
...(configuration.auth?.credentials ? { credentials: configuration.auth.credentials } : {}),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
259
|
+
throw error;
|
|
260
|
+
throw new Error(`Could not reach OpenAPI endpoint ${requestUrl}: ${error instanceof Error ? error.message : String(error)}`, {
|
|
261
|
+
cause: error,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
let result;
|
|
265
|
+
const errorResponse = response.ok ? undefined : response.clone();
|
|
266
|
+
const declaredContent = options.responseTypes?.[response.status] ??
|
|
267
|
+
options.responseTypes?.[`${Math.floor(response.status / 100)}XX`] ??
|
|
268
|
+
options.responseTypes?.default;
|
|
269
|
+
const mime = response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
270
|
+
const declaredType = declaredContent?.[mime] ?? declaredContent?.[`${mime.split('/')[0]}/*`] ?? declaredContent?.['*/*'];
|
|
271
|
+
const responseType = options.responseTypes
|
|
272
|
+
? declaredType === 'blob'
|
|
273
|
+
? 'blob'
|
|
274
|
+
: undefined
|
|
275
|
+
: response.ok
|
|
276
|
+
? options.responseType
|
|
277
|
+
: undefined;
|
|
278
|
+
try {
|
|
279
|
+
result = options.method.toUpperCase() === 'HEAD' ? undefined : await readResponse(response, responseType);
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
283
|
+
throw error;
|
|
284
|
+
if (!response.ok) {
|
|
285
|
+
result = errorResponse ? await errorResponse.text().catch(() => undefined) : undefined;
|
|
286
|
+
throw new OpenapiHttpError(response.status, response.statusText, requestUrl, result);
|
|
287
|
+
}
|
|
288
|
+
throw new Error(`Could not read response from ${requestUrl}: ${error instanceof Error ? error.message : String(error)}`, {
|
|
289
|
+
cause: error,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (!response.ok) {
|
|
293
|
+
throw new OpenapiHttpError(response.status, response.statusText, requestUrl, result);
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=openapi-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi-runtime.js","sourceRoot":"","sources":["../src/openapi-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
export type TokenStorage = 'localStorage' | 'sessionStorage' | 'cookie' | 'none';
|
|
2
|
+
|
|
3
|
+
export interface AuthConfig {
|
|
4
|
+
storage: TokenStorage;
|
|
5
|
+
key?: string;
|
|
6
|
+
scheme?: string | false;
|
|
7
|
+
credentials?: RequestCredentials;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface OpenapiFetcherOptions<TBody, THeaders, TQueryParams, TPathParams> {
|
|
11
|
+
body?: TBody;
|
|
12
|
+
headers?: THeaders;
|
|
13
|
+
method: string;
|
|
14
|
+
pathParams?: TPathParams;
|
|
15
|
+
queryParams?: TQueryParams;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
url: string;
|
|
18
|
+
contentType?: string;
|
|
19
|
+
accept?: string;
|
|
20
|
+
responseType?: 'blob';
|
|
21
|
+
/** Response status -> media type -> decoder. Exact statuses/media types take precedence over ranges and wildcards. */
|
|
22
|
+
responseTypes?: Record<string, Record<string, 'blob' | 'auto'>>;
|
|
23
|
+
parameters?: OpenapiParameter[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface OpenapiParameter {
|
|
27
|
+
name: string;
|
|
28
|
+
in: 'path' | 'query' | 'header';
|
|
29
|
+
style: 'simple' | 'form' | 'deepObject' | 'spaceDelimited' | 'pipeDelimited';
|
|
30
|
+
explode: boolean;
|
|
31
|
+
required: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface OpenapiFetcherConfiguration {
|
|
35
|
+
/** Custom value for the `Authorization` header. When omitted, no authorization header is added unless `auth` is configured. */
|
|
36
|
+
getToken?: () => string | null | undefined;
|
|
37
|
+
/** Base URL prepended to paths from the OpenAPI document. */
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
/** Token storage and fetch credential settings. */
|
|
40
|
+
auth?: AuthConfig;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function readConfiguredToken(auth: AuthConfig): string {
|
|
44
|
+
if (auth.storage === 'none') return '';
|
|
45
|
+
if (auth.storage === 'cookie') {
|
|
46
|
+
if (typeof document === 'undefined' || !auth.key) return '';
|
|
47
|
+
const cookie = document.cookie
|
|
48
|
+
.split(';')
|
|
49
|
+
.map((part) => part.trim())
|
|
50
|
+
.find((part) => part.startsWith(`${auth.key}=`));
|
|
51
|
+
if (!cookie) return '';
|
|
52
|
+
const value = cookie.slice(auth.key.length + 1);
|
|
53
|
+
try {
|
|
54
|
+
return decodeURIComponent(value);
|
|
55
|
+
} catch {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (typeof globalThis[auth.storage] === 'undefined' || !auth.key) return '';
|
|
60
|
+
return globalThis[auth.storage].getItem(auth.key) ?? '';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function authorizationValue(configuration: OpenapiFetcherConfiguration): string {
|
|
64
|
+
if (configuration.getToken) return configuration.getToken() ?? '';
|
|
65
|
+
const auth = configuration.auth;
|
|
66
|
+
if (!auth) return '';
|
|
67
|
+
const token = readConfiguredToken(auth);
|
|
68
|
+
if (!token || auth.scheme === false) return token;
|
|
69
|
+
const scheme = auth.scheme ?? 'Bearer';
|
|
70
|
+
if (!scheme) return token;
|
|
71
|
+
return token.toLowerCase().startsWith(`${scheme.toLowerCase()} `) ? token : `${scheme} ${token}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function withBaseUrl(baseUrl: string | undefined, url: string): string {
|
|
75
|
+
if (!baseUrl || /^[a-z][a-z\d+.-]*:\/\//i.test(url)) return url;
|
|
76
|
+
return `${baseUrl.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export class OpenapiHttpError<TError = unknown> extends Error {
|
|
80
|
+
constructor(
|
|
81
|
+
readonly status: number,
|
|
82
|
+
readonly statusText: string,
|
|
83
|
+
readonly url: string,
|
|
84
|
+
readonly data: TError,
|
|
85
|
+
) {
|
|
86
|
+
super(`HTTP ${status}${statusText ? ` ${statusText}` : ''} for ${url}.`);
|
|
87
|
+
this.name = 'OpenapiHttpError';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function parameterScalar(value: unknown): string {
|
|
92
|
+
if (value === null) return '';
|
|
93
|
+
if (typeof value === 'object' || value === undefined) throw new TypeError('OpenAPI parameters must contain scalar values.');
|
|
94
|
+
return String(value);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function parameterParts(value: unknown, explode: boolean, encode: (value: string) => string): string[] {
|
|
98
|
+
if (Array.isArray(value)) return value.map((item) => encode(parameterScalar(item)));
|
|
99
|
+
if (value !== null && typeof value === 'object') {
|
|
100
|
+
return Object.entries(value).flatMap(([key, item]) => {
|
|
101
|
+
const pair = [encode(key), encode(parameterScalar(item))];
|
|
102
|
+
return explode ? [pair.join('=')] : pair;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return [encode(parameterScalar(value))];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function serializeQueryParams(queryParams: unknown, parameters: OpenapiParameter[] = []): string {
|
|
109
|
+
const result: string[] = [];
|
|
110
|
+
const append = (key: string, encodedValue: string): void => {
|
|
111
|
+
result.push(`${encodeURIComponent(key)}=${encodedValue}`);
|
|
112
|
+
};
|
|
113
|
+
if (queryParams == null) return '';
|
|
114
|
+
if (queryParams instanceof URLSearchParams) return queryParams.toString();
|
|
115
|
+
if (typeof queryParams !== 'object' || Array.isArray(queryParams)) {
|
|
116
|
+
throw new TypeError('OpenAPI query parameters must be an object.');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
120
|
+
if (value === undefined) continue;
|
|
121
|
+
const parameter = parameters.find((item) => item.in === 'query' && item.name === key);
|
|
122
|
+
const style = parameter?.style ?? 'form';
|
|
123
|
+
const explode = parameter?.explode ?? true;
|
|
124
|
+
if (style === 'deepObject') {
|
|
125
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) throw new TypeError(`deepObject requires an object: ${key}`);
|
|
126
|
+
for (const [name, item] of Object.entries(value)) append(`${key}[${name}]`, encodeURIComponent(parameterScalar(item)));
|
|
127
|
+
} else if (style === 'form' && explode && value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
128
|
+
for (const [name, item] of Object.entries(value)) append(name, encodeURIComponent(parameterScalar(item)));
|
|
129
|
+
} else if (explode && Array.isArray(value)) {
|
|
130
|
+
for (const item of value) append(key, encodeURIComponent(parameterScalar(item)));
|
|
131
|
+
} else {
|
|
132
|
+
const separator = style === 'spaceDelimited' ? '%20' : style === 'pipeDelimited' ? '|' : ',';
|
|
133
|
+
append(key, parameterParts(value, false, encodeURIComponent).join(separator));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return result.join('&');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isJsonContentType(contentType: string): boolean {
|
|
140
|
+
const mime = contentType.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
141
|
+
return mime === 'application/json' || /^application\/[^/;\s]+\+json$/.test(mime);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function requestBody(body: unknown, contentType: string): BodyInit | undefined {
|
|
145
|
+
if (body === undefined) return undefined;
|
|
146
|
+
if (body instanceof FormData || body instanceof Blob || body instanceof URLSearchParams) return body;
|
|
147
|
+
if (isJsonContentType(contentType)) return JSON.stringify(body);
|
|
148
|
+
if (contentType === 'multipart/form-data' || contentType === 'application/x-www-form-urlencoded') {
|
|
149
|
+
if (body === null || typeof body !== 'object' || Array.isArray(body)) throw new TypeError(`${contentType} requires an object body.`);
|
|
150
|
+
const form = new FormData();
|
|
151
|
+
for (const [key, value] of Object.entries(body)) {
|
|
152
|
+
if (value === undefined) continue;
|
|
153
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
154
|
+
if (item instanceof Blob) form.append(key, item);
|
|
155
|
+
else if (item !== null && typeof item === 'object') {
|
|
156
|
+
const json = JSON.stringify(item);
|
|
157
|
+
form.append(key, contentType === 'multipart/form-data' ? new Blob([json], { type: 'application/json' }) : json);
|
|
158
|
+
} else form.append(key, parameterScalar(item));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (contentType === 'multipart/form-data') return form;
|
|
162
|
+
const params = new URLSearchParams();
|
|
163
|
+
form.forEach((value, key) => {
|
|
164
|
+
if (typeof value !== 'string') throw new TypeError('URL-encoded bodies cannot contain binary files.');
|
|
165
|
+
params.append(key, value);
|
|
166
|
+
});
|
|
167
|
+
return params;
|
|
168
|
+
}
|
|
169
|
+
if (typeof body === 'string') return body;
|
|
170
|
+
throw new TypeError(`Unsupported request body for content type ${contentType}.`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function requestHeaders(value: unknown, parameters: OpenapiParameter[]): Headers {
|
|
174
|
+
if (value instanceof Headers || Array.isArray(value)) return new Headers(value);
|
|
175
|
+
const headers = new Headers();
|
|
176
|
+
if (value && typeof value === 'object') {
|
|
177
|
+
for (const [key, item] of Object.entries(value)) {
|
|
178
|
+
if (item === undefined) continue;
|
|
179
|
+
const parameter = parameters.find((entry) => entry.in === 'header' && entry.name.toLowerCase() === key.toLowerCase());
|
|
180
|
+
headers.set(key, parameterParts(item, parameter?.explode ?? false, (part) => part).join(','));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return headers;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function withQueryParams(url: string, serialized: string): string {
|
|
187
|
+
if (!serialized) return url;
|
|
188
|
+
const hashIndex = url.indexOf('#');
|
|
189
|
+
const base = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
190
|
+
const hash = hashIndex === -1 ? '' : url.slice(hashIndex);
|
|
191
|
+
const separator = base.includes('?') ? (base.endsWith('?') || base.endsWith('&') ? '' : '&') : '?';
|
|
192
|
+
return `${base}${separator}${serialized}${hash}`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function readResponse(response: Response, responseType?: 'blob'): Promise<unknown> {
|
|
196
|
+
if (response.status === 204 || response.status === 205) return undefined;
|
|
197
|
+
if (responseType === 'blob') return await response.blob();
|
|
198
|
+
const contentType = response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
199
|
+
const json = isJsonContentType(contentType);
|
|
200
|
+
if (contentType.startsWith('text/') || (!json && contentType.includes('xml'))) return await response.text();
|
|
201
|
+
if (response.body === null || response.headers.get('content-length') === '0') return undefined;
|
|
202
|
+
if (json) return await response.json();
|
|
203
|
+
return await response.blob();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function createOpenapiFetcher(configuration: OpenapiFetcherConfiguration = {}) {
|
|
207
|
+
return async function openapiFetcher<
|
|
208
|
+
TData,
|
|
209
|
+
TError = unknown,
|
|
210
|
+
TBody = unknown,
|
|
211
|
+
THeaders = unknown,
|
|
212
|
+
TQueryParams = unknown,
|
|
213
|
+
TPathParams = unknown,
|
|
214
|
+
>(options: OpenapiFetcherOptions<TBody, THeaders, TQueryParams, TPathParams>): Promise<TData> {
|
|
215
|
+
try {
|
|
216
|
+
const parameters = options.parameters ?? [];
|
|
217
|
+
const headers = new Headers();
|
|
218
|
+
const contentType = options.contentType ?? 'application/json';
|
|
219
|
+
if (options.body !== undefined) {
|
|
220
|
+
if (contentType === '*/*') {
|
|
221
|
+
if (!(options.body instanceof Blob)) throw new TypeError('Wildcard request content requires a Blob body.');
|
|
222
|
+
headers.set('content-type', options.body.type || 'application/octet-stream');
|
|
223
|
+
} else {
|
|
224
|
+
headers.set('content-type', contentType);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (options.accept) headers.set('accept', options.accept);
|
|
228
|
+
const token = authorizationValue(configuration);
|
|
229
|
+
if (token) headers.set('authorization', token);
|
|
230
|
+
requestHeaders(options.headers, parameters).forEach((value, key) => {
|
|
231
|
+
headers.set(key, value);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const body = requestBody(options.body, headers.get('content-type') ?? contentType);
|
|
235
|
+
if (body instanceof FormData) headers.delete('content-type');
|
|
236
|
+
|
|
237
|
+
for (const parameter of parameters) {
|
|
238
|
+
if (!parameter.required || parameter.in === 'path') continue;
|
|
239
|
+
const value =
|
|
240
|
+
parameter.in === 'header'
|
|
241
|
+
? headers.get(parameter.name)
|
|
242
|
+
: (options.queryParams as Record<string, unknown> | undefined)?.[parameter.name];
|
|
243
|
+
if (value === undefined || (parameter.in === 'header' && value === null))
|
|
244
|
+
throw new Error(`Missing required OpenAPI ${parameter.in} parameter "${parameter.name}" for ${options.url}.`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const pathParams = options.pathParams as Record<string, unknown> | undefined;
|
|
248
|
+
const path = options.url.replace(/\{([^}]+)}/g, (_match, key: string) => {
|
|
249
|
+
const value = pathParams?.[key];
|
|
250
|
+
if (value === undefined || value === null) throw new Error(`Missing required OpenAPI path parameter "${key}" for ${options.url}.`);
|
|
251
|
+
const parameter = parameters.find((item) => item.in === 'path' && item.name === key);
|
|
252
|
+
return parameterParts(value, parameter?.explode ?? false, encodeURIComponent).join(',');
|
|
253
|
+
});
|
|
254
|
+
const pathSegments = path.split(/[?#]/, 1)[0]?.split('/') ?? [];
|
|
255
|
+
if (pathSegments.some((segment) => /^(?:\.|%2e){1,2}$/i.test(segment))) {
|
|
256
|
+
throw new Error(`OpenAPI path contains a dot segment that Fetch would normalize: ${options.url}.`);
|
|
257
|
+
}
|
|
258
|
+
const url = withBaseUrl(configuration.baseUrl, path);
|
|
259
|
+
const queryParams = serializeQueryParams(options.queryParams, parameters);
|
|
260
|
+
const requestUrl = withQueryParams(url, queryParams);
|
|
261
|
+
let response: Response;
|
|
262
|
+
try {
|
|
263
|
+
response = await fetch(requestUrl, {
|
|
264
|
+
...(body === undefined ? {} : { body }),
|
|
265
|
+
headers,
|
|
266
|
+
method: options.method.toUpperCase(),
|
|
267
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
268
|
+
...(configuration.auth?.credentials ? { credentials: configuration.auth.credentials } : {}),
|
|
269
|
+
});
|
|
270
|
+
} catch (error) {
|
|
271
|
+
if (error instanceof Error && error.name === 'AbortError') throw error;
|
|
272
|
+
throw new Error(`Could not reach OpenAPI endpoint ${requestUrl}: ${error instanceof Error ? error.message : String(error)}`, {
|
|
273
|
+
cause: error,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let result: unknown;
|
|
278
|
+
const errorResponse = response.ok ? undefined : response.clone();
|
|
279
|
+
const declaredContent =
|
|
280
|
+
options.responseTypes?.[response.status] ??
|
|
281
|
+
options.responseTypes?.[`${Math.floor(response.status / 100)}XX`] ??
|
|
282
|
+
options.responseTypes?.default;
|
|
283
|
+
const mime = response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase() ?? '';
|
|
284
|
+
const declaredType = declaredContent?.[mime] ?? declaredContent?.[`${mime.split('/')[0]}/*`] ?? declaredContent?.['*/*'];
|
|
285
|
+
const responseType = options.responseTypes
|
|
286
|
+
? declaredType === 'blob'
|
|
287
|
+
? 'blob'
|
|
288
|
+
: undefined
|
|
289
|
+
: response.ok
|
|
290
|
+
? options.responseType
|
|
291
|
+
: undefined;
|
|
292
|
+
try {
|
|
293
|
+
result = options.method.toUpperCase() === 'HEAD' ? undefined : await readResponse(response, responseType);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (error instanceof Error && error.name === 'AbortError') throw error;
|
|
296
|
+
if (!response.ok) {
|
|
297
|
+
result = errorResponse ? await errorResponse.text().catch(() => undefined) : undefined;
|
|
298
|
+
throw new OpenapiHttpError(response.status, response.statusText, requestUrl, result);
|
|
299
|
+
}
|
|
300
|
+
throw new Error(`Could not read response from ${requestUrl}: ${error instanceof Error ? error.message : String(error)}`, {
|
|
301
|
+
cause: error,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (!response.ok) {
|
|
305
|
+
throw new OpenapiHttpError<TError>(response.status, response.statusText, requestUrl, result as TError);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return result as TData;
|
|
309
|
+
} catch (error) {
|
|
310
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
storage: TokenStorage;
|
|
4
|
-
key?: string;
|
|
5
|
-
scheme?: string | false;
|
|
6
|
-
credentials?: RequestCredentials;
|
|
7
|
-
}
|
|
1
|
+
import type { AuthConfig } from './openapi-runtime.js';
|
|
2
|
+
export type { AuthConfig, TokenStorage } from './openapi-runtime.js';
|
|
8
3
|
export interface CodegenConfig {
|
|
9
4
|
auth?: AuthConfig;
|
|
10
5
|
openapi?: {
|