@spec2ts/openapi-client 3.1.2 → 4.0.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.
@@ -1,271 +0,0 @@
1
- export const defaults: RequestOptions = {
2
- baseUrl: "/",
3
- };
4
-
5
- export const servers = {};
6
-
7
- export type RequestOptions = {
8
- baseUrl?: string;
9
- fetch?: typeof fetch;
10
- headers?: Record<string, string | undefined>;
11
- } & Omit<RequestInit, "body" | "headers">;
12
-
13
- export type ApiResponse<T> = {
14
- status: number;
15
- statusText: string;
16
- headers: Record<string, string>;
17
- data: T;
18
- };
19
-
20
- type Encoders = Array<(s: string) => string>;
21
- type TagFunction = (strings: TemplateStringsArray, ...values: any[]) => string;
22
-
23
- type FetchRequestOptions = RequestOptions & {
24
- body?: string | FormData;
25
- };
26
-
27
- type JsonRequestOptions = RequestOptions & {
28
- body: unknown;
29
- };
30
-
31
- type FormRequestOptions<T extends Record<string, unknown>> = RequestOptions & {
32
- body: T;
33
- };
34
-
35
- type MultipartRequestOptions = RequestOptions & {
36
- body: Record<string, any>; // string | Blob
37
- };
38
-
39
- /** Utilities functions */
40
- export const _ = {
41
- // Encode param names and values as URIComponent
42
- encodeReserved: [encodeURI, encodeURIComponent],
43
- allowReserved: [encodeURI, encodeURI],
44
-
45
- /** Deeply remove all properties with undefined values. */
46
- stripUndefined<T extends Record<string, U | undefined>, U>(obj?: T): Record<string, U> | undefined {
47
- return obj && JSON.parse(JSON.stringify(obj));
48
- },
49
-
50
- isEmpty(v: unknown): boolean {
51
- return typeof v === "object" && !!v ?
52
- Object.keys(v).length === 0 && v.constructor === Object :
53
- v === undefined;
54
- },
55
-
56
- /** Creates a tag-function to encode template strings with the given encoders. */
57
- encode(encoders: Encoders, delimiter = ","): TagFunction {
58
- return (strings: TemplateStringsArray, ...values: any[]) => {
59
- return strings.reduce((prev, s, i) => `${prev}${s}${q(values[i] ?? "", i)}`, "");
60
- };
61
-
62
- function q(v: any, i: number): string {
63
- const encoder = encoders[i % encoders.length];
64
- if (typeof v === "object") {
65
- if (Array.isArray(v)) {
66
- return v.map(encoder).join(delimiter);
67
- }
68
- const flat = Object.entries(v).reduce(
69
- (flat, entry) => [...flat, ...entry],
70
- [] as any
71
- );
72
- return flat.map(encoder).join(delimiter);
73
- }
74
-
75
- return encoder(String(v));
76
- }
77
- },
78
-
79
- /** Separate array values by the given delimiter. */
80
- delimited(delimiter = ","): (params: Record<string, any>, encoders?: Encoders) => string {
81
- return (params: Record<string, any>, encoders = _.encodeReserved) =>
82
- Object.entries(params)
83
- .filter(([, value]) => !_.isEmpty(value))
84
- .map(([name, value]) => _.encode(encoders, delimiter)`${name}=${value}`)
85
- .join("&");
86
- },
87
-
88
- /** Join URLs parts. */
89
- joinUrl(...parts: Array<string | undefined>): string {
90
- return parts
91
- .filter(Boolean)
92
- .join("/")
93
- .replace(/([^:]\/)\/+/, "$1");
94
- }
95
- };
96
-
97
- /** Functions to serialize query parameters in different styles. */
98
- export const QS = {
99
- /** Join params using an ampersand and prepends a questionmark if not empty. */
100
- query(...params: string[]): string {
101
- const s = params.filter(p => !!p).join("&");
102
- return s && `?${s}`;
103
- },
104
-
105
- /**
106
- * Serializes nested objects according to the `deepObject` style specified in
107
- * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#style-values
108
- */
109
- deep(params: Record<string, any>, [k, v] = _.encodeReserved): string {
110
- const qk = _.encode([(s) => s, k]);
111
- const qv = _.encode([(s) => s, v]);
112
- // don't add index to arrays
113
- // https://github.com/expressjs/body-parser/issues/289
114
- const visit = (obj: any, prefix = ""): string =>
115
- Object.entries(obj)
116
- .filter(([, v]) => !_.isEmpty(v))
117
- .map(([prop, v]) => {
118
- const isValueObject = typeof v === "object";
119
- const index = Array.isArray(obj) && !isValueObject ? "" : prop;
120
- const key = prefix ? qk`${prefix}[${index}]` : prop;
121
- if (isValueObject) {
122
- return visit(v, key);
123
- }
124
- return qv`${key}=${v}`;
125
- })
126
- .join("&");
127
-
128
- return visit(params);
129
- },
130
-
131
- /**
132
- * Property values of type array or object generate separate parameters
133
- * for each value of the array, or key-value-pair of the map.
134
- * For other types of properties this property has no effect.
135
- * See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#encoding-object
136
- */
137
- explode(params: Record<string, any>, encoders = _.encodeReserved): string {
138
- const q = _.encode(encoders);
139
- return Object.entries(params)
140
- .filter(([, value]) => typeof value !== "undefined")
141
- .map(([name, value]) => {
142
- if (Array.isArray(value)) {
143
- return value.map((v) => q`${name}=${v}`).join("&");
144
- }
145
-
146
- if (typeof value === "object") {
147
- return QS.explode(value, encoders);
148
- }
149
-
150
- return q`${name}=${value}`;
151
- })
152
- .join("&");
153
- },
154
-
155
- form: _.delimited(),
156
- pipe: _.delimited("|"),
157
- space: _.delimited("%20"),
158
- };
159
-
160
- /** Http request base methods. */
161
- export const http = {
162
- async fetch(url: string, req?: FetchRequestOptions): Promise<ApiResponse<string | undefined>> {
163
- const { baseUrl, headers, fetch: customFetch, ...init } = { ...defaults, ...req };
164
- const href = _.joinUrl(baseUrl, url);
165
- const res = await (customFetch || fetch)(href, {
166
- ...init,
167
- headers: _.stripUndefined({ ...defaults.headers, ...headers }),
168
- });
169
-
170
- let text: string | undefined;
171
- try { text = await res.text(); }
172
- catch (err) { /* ok */ }
173
-
174
- if (!res.ok) {
175
- throw new HttpError(res.status, res.statusText, href, res.headers, text);
176
- }
177
-
178
- return {
179
- status: res.status,
180
- statusText: res.statusText,
181
- headers: http.headers(res.headers),
182
- data: text
183
- };
184
- },
185
-
186
- async fetchJson(url: string, req: FetchRequestOptions = {}): Promise<ApiResponse<any>> {
187
- const res = await http.fetch(url, {
188
- ...req,
189
- headers: {
190
- ...req.headers,
191
- Accept: "application/json",
192
- },
193
- });
194
-
195
- res.data = res.data && JSON.parse(res.data);
196
- return res;
197
- },
198
-
199
- async fetchVoid(url: string, req: FetchRequestOptions = {}): Promise<ApiResponse<undefined>> {
200
- const res = await http.fetch(url, {
201
- ...req,
202
- headers: {
203
- ...req.headers,
204
- Accept: "application/json",
205
- },
206
- });
207
-
208
- return res as ApiResponse<undefined>;
209
- },
210
-
211
- json({ body, headers, ...req }: JsonRequestOptions): FetchRequestOptions {
212
- return {
213
- ...req,
214
- body: JSON.stringify(body),
215
- headers: {
216
- ...headers,
217
- "Content-Type": "application/json",
218
- },
219
- };
220
- },
221
-
222
- form<T extends Record<string, unknown>>({ body, headers, ...req }: FormRequestOptions<T>): FetchRequestOptions {
223
- return {
224
- ...req,
225
- body: QS.form(body),
226
- headers: {
227
- ...headers,
228
- "Content-Type": "application/x-www-form-urlencoded",
229
- },
230
- };
231
- },
232
-
233
- multipart({ body, ...req }: MultipartRequestOptions): FetchRequestOptions {
234
- const data = new FormData();
235
- Object.entries(body).forEach(([name, value]) => {
236
- data.append(name, value);
237
- });
238
- return {
239
- ...req,
240
- body: data,
241
- };
242
- },
243
-
244
- headers(headers: Headers): Record<string, string> {
245
- const res: Record<string, string> = {};
246
- headers.forEach((value, key) => res[key] = value);
247
- return res;
248
- }
249
- };
250
-
251
- export class HttpError extends Error {
252
- status: number;
253
- statusText: string;
254
- headers: Record<string, string>;
255
- data?: Record<string, unknown>;
256
-
257
- constructor(status: number, statusText: string, url: string, headers: Headers, text?: string) {
258
- super(`${url} - ${statusText} (${status})`);
259
- this.status = status;
260
- this.statusText = statusText;
261
- this.headers = http.headers(headers);
262
-
263
- if (text) {
264
- try { this.data = JSON.parse(text); }
265
- catch (err) { /* ok */ }
266
- }
267
- }
268
- }
269
-
270
- /** Utility Type to extract returns type from a method. */
271
- export type ApiResult<Fn> = Fn extends (...args: any) => Promise<ApiResponse<infer T>> ? T : never;
package/lib/util.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function camelCase(str: string): string;
package/lib/util.js DELETED
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.camelCase = void 0;
4
- function camelCase(str) {
5
- const regex = /[A-Z\xC0-\xD6\xD8-\xDE_$]?[a-z\xDF-\xF6\xF8-\xFF_$]+|[A-Z\xC0-\xD6\xD8-\xDE_$]+(?![a-z\xDF-\xF6\xF8-\xFF_$])|\d+/g;
6
- const words = str.match(regex);
7
- if (!words)
8
- return "";
9
- let result = "";
10
- const len = words.length;
11
- for (let i = 0; i < len; i++) {
12
- const word = words[i];
13
- let tmp = word.toLowerCase();
14
- if (i !== 0) {
15
- tmp = tmp[0].toUpperCase() + tmp.substr(1);
16
- }
17
- result += tmp;
18
- }
19
- return result;
20
- }
21
- exports.camelCase = camelCase;