@ps-aux/api-client-axios 0.7.0-rc.3 → 0.7.0-rc.5

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/dist/browser.cjs CHANGED
@@ -160,21 +160,34 @@ class HttpClientHelper {
160
160
  }
161
161
  }
162
162
 
163
+ const noOpInterceptor = () => (context, next) => next(context);
164
+
165
+ const HTTP_CLIENT_FIELD = "http";
166
+ const unwrap = (api) => {
167
+ const candidate = api[HTTP_CLIENT_FIELD];
168
+ if (!candidate || typeof candidate !== "object" || typeof candidate.request !== "function") {
169
+ throw new TypeError(
170
+ "Expected a generated API instance backed by a PromiseHttpClient"
171
+ );
172
+ }
173
+ return candidate;
174
+ };
175
+
163
176
  const createHttpClient$1 = (axios, opts) => {
164
177
  const { querySerializer } = opts;
165
178
  const helper = new HttpClientHelper();
166
179
  return {
167
180
  request: (req) => {
168
181
  helper.validateRequest(req);
169
- const { query, requestContentType, body, headers: reqHeaders } = req;
182
+ const { query, contentType, body, headers: reqHeaders } = req;
170
183
  const paramsSerializer = querySerializer ? (r) => helper.serializeQuery(r, querySerializer) : void 0;
171
- const isBlobResponse = req.format === "document";
184
+ const isBlobResponse = req.responseFormat === "document";
172
185
  const headers = { ...reqHeaders || {} };
173
186
  let data = body;
174
- if (requestContentType === "multipart/form-data") {
187
+ if (contentType === "multipart/form-data") {
175
188
  data = helper.convertToFormData(body);
176
- } else if (requestContentType) {
177
- headers["Content-Type"] = requestContentType;
189
+ } else if (contentType) {
190
+ headers["Content-Type"] = contentType;
178
191
  }
179
192
  return axios.request({
180
193
  method: req.method,
@@ -237,3 +250,5 @@ const createHttpClient = (axios, opts) => {
237
250
  };
238
251
 
239
252
  exports.createHttpClient = createHttpClient;
253
+ exports.noOpInterceptor = noOpInterceptor;
254
+ exports.unwrap = unwrap;
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
package/dist/browser.d.ts CHANGED
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
package/dist/browser.mjs CHANGED
@@ -158,21 +158,34 @@ class HttpClientHelper {
158
158
  }
159
159
  }
160
160
 
161
+ const noOpInterceptor = () => (context, next) => next(context);
162
+
163
+ const HTTP_CLIENT_FIELD = "http";
164
+ const unwrap = (api) => {
165
+ const candidate = api[HTTP_CLIENT_FIELD];
166
+ if (!candidate || typeof candidate !== "object" || typeof candidate.request !== "function") {
167
+ throw new TypeError(
168
+ "Expected a generated API instance backed by a PromiseHttpClient"
169
+ );
170
+ }
171
+ return candidate;
172
+ };
173
+
161
174
  const createHttpClient$1 = (axios, opts) => {
162
175
  const { querySerializer } = opts;
163
176
  const helper = new HttpClientHelper();
164
177
  return {
165
178
  request: (req) => {
166
179
  helper.validateRequest(req);
167
- const { query, requestContentType, body, headers: reqHeaders } = req;
180
+ const { query, contentType, body, headers: reqHeaders } = req;
168
181
  const paramsSerializer = querySerializer ? (r) => helper.serializeQuery(r, querySerializer) : void 0;
169
- const isBlobResponse = req.format === "document";
182
+ const isBlobResponse = req.responseFormat === "document";
170
183
  const headers = { ...reqHeaders || {} };
171
184
  let data = body;
172
- if (requestContentType === "multipart/form-data") {
185
+ if (contentType === "multipart/form-data") {
173
186
  data = helper.convertToFormData(body);
174
- } else if (requestContentType) {
175
- headers["Content-Type"] = requestContentType;
187
+ } else if (contentType) {
188
+ headers["Content-Type"] = contentType;
176
189
  }
177
190
  return axios.request({
178
191
  method: req.method,
@@ -234,4 +247,4 @@ const createHttpClient = (axios, opts) => {
234
247
  });
235
248
  };
236
249
 
237
- export { createHttpClient };
250
+ export { createHttpClient, noOpInterceptor, unwrap };
package/dist/node.cjs CHANGED
@@ -160,21 +160,34 @@ class HttpClientHelper {
160
160
  }
161
161
  }
162
162
 
163
+ const noOpInterceptor = () => (context, next) => next(context);
164
+
165
+ const HTTP_CLIENT_FIELD = "http";
166
+ const unwrap = (api) => {
167
+ const candidate = api[HTTP_CLIENT_FIELD];
168
+ if (!candidate || typeof candidate !== "object" || typeof candidate.request !== "function") {
169
+ throw new TypeError(
170
+ "Expected a generated API instance backed by a PromiseHttpClient"
171
+ );
172
+ }
173
+ return candidate;
174
+ };
175
+
163
176
  const createHttpClient$1 = (axios, opts) => {
164
177
  const { querySerializer } = opts;
165
178
  const helper = new HttpClientHelper();
166
179
  return {
167
180
  request: (req) => {
168
181
  helper.validateRequest(req);
169
- const { query, requestContentType, body, headers: reqHeaders } = req;
182
+ const { query, contentType, body, headers: reqHeaders } = req;
170
183
  const paramsSerializer = querySerializer ? (r) => helper.serializeQuery(r, querySerializer) : void 0;
171
- const isBlobResponse = req.format === "document";
184
+ const isBlobResponse = req.responseFormat === "document";
172
185
  const headers = { ...reqHeaders || {} };
173
186
  let data = body;
174
- if (requestContentType === "multipart/form-data") {
187
+ if (contentType === "multipart/form-data") {
175
188
  data = helper.convertToFormData(body);
176
- } else if (requestContentType) {
177
- headers["Content-Type"] = requestContentType;
189
+ } else if (contentType) {
190
+ headers["Content-Type"] = contentType;
178
191
  }
179
192
  return axios.request({
180
193
  method: req.method,
@@ -237,3 +250,5 @@ const createHttpClient = (axios, opts) => {
237
250
  };
238
251
 
239
252
  exports.createHttpClient = createHttpClient;
253
+ exports.noOpInterceptor = noOpInterceptor;
254
+ exports.unwrap = unwrap;
package/dist/node.d.cts CHANGED
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
package/dist/node.d.mts CHANGED
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
package/dist/node.d.ts CHANGED
@@ -4,14 +4,14 @@ type KnownRequestContentType = 'application/json' | 'multipart/form-data' | 'app
4
4
  type RequestContentType = KnownRequestContentType | string;
5
5
  type QueryValue = string | number | boolean | null | undefined | QueryValue[] | Record<string, any> | unknown;
6
6
  type QueryParams = Record<string, QueryValue>;
7
- type Request = {
7
+ type HttpRequest = {
8
8
  path: string;
9
9
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
10
- format?: 'json' | 'document';
10
+ responseFormat?: 'json' | 'document';
11
11
  headers?: Record<string, string>;
12
12
  query?: QueryParams;
13
13
  body?: any;
14
- requestContentType?: RequestContentType;
14
+ contentType?: RequestContentType;
15
15
  };
16
16
  type HttpResponse<Data> = {
17
17
  body: Data;
@@ -21,9 +21,18 @@ type HttpResponse<Data> = {
21
21
  type QuerySerializer = (params: QueryParams) => string;
22
22
 
23
23
  type HttpClient<RequestParams = never> = {
24
- request: <Data>(req: Request, params?: RequestParams) => Promise<HttpResponse<Data>>;
24
+ request: <Data>(req: HttpRequest, params?: RequestParams) => Promise<HttpResponse<Data>>;
25
25
  };
26
26
 
27
+ type HttpClientInterceptorContext<P = never> = {
28
+ request: HttpRequest;
29
+ params?: P;
30
+ };
31
+ type HttpClientInterceptor<P = never> = <D>(ctx: HttpClientInterceptorContext<P>, next: (ctx: HttpClientInterceptorContext<P>) => Promise<HttpResponse<D>>) => Promise<HttpResponse<D>>;
32
+ declare const noOpInterceptor: <P = never>() => HttpClientInterceptor<P>;
33
+
34
+ declare const unwrap: <RequestParams = never>(api: object) => HttpClient<RequestParams>;
35
+
27
36
  /// <reference lib="esnext.asynciterable" />
28
37
 
29
38
  /**
@@ -40,5 +49,5 @@ declare const createHttpClient: (axios: AxiosInstance, opts: {
40
49
  querySerializer: QuerySerializer | null;
41
50
  }) => HttpClient;
42
51
 
43
- export { createHttpClient };
44
- export type { HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
52
+ export { createHttpClient, noOpInterceptor, unwrap };
53
+ export type { HttpClientInterceptor, HttpClientInterceptorContext, HttpRequest, HttpResponse, HttpClient as PromiseHttpClient, QuerySerializer };
package/dist/node.mjs CHANGED
@@ -158,21 +158,34 @@ class HttpClientHelper {
158
158
  }
159
159
  }
160
160
 
161
+ const noOpInterceptor = () => (context, next) => next(context);
162
+
163
+ const HTTP_CLIENT_FIELD = "http";
164
+ const unwrap = (api) => {
165
+ const candidate = api[HTTP_CLIENT_FIELD];
166
+ if (!candidate || typeof candidate !== "object" || typeof candidate.request !== "function") {
167
+ throw new TypeError(
168
+ "Expected a generated API instance backed by a PromiseHttpClient"
169
+ );
170
+ }
171
+ return candidate;
172
+ };
173
+
161
174
  const createHttpClient$1 = (axios, opts) => {
162
175
  const { querySerializer } = opts;
163
176
  const helper = new HttpClientHelper();
164
177
  return {
165
178
  request: (req) => {
166
179
  helper.validateRequest(req);
167
- const { query, requestContentType, body, headers: reqHeaders } = req;
180
+ const { query, contentType, body, headers: reqHeaders } = req;
168
181
  const paramsSerializer = querySerializer ? (r) => helper.serializeQuery(r, querySerializer) : void 0;
169
- const isBlobResponse = req.format === "document";
182
+ const isBlobResponse = req.responseFormat === "document";
170
183
  const headers = { ...reqHeaders || {} };
171
184
  let data = body;
172
- if (requestContentType === "multipart/form-data") {
185
+ if (contentType === "multipart/form-data") {
173
186
  data = helper.convertToFormData(body);
174
- } else if (requestContentType) {
175
- headers["Content-Type"] = requestContentType;
187
+ } else if (contentType) {
188
+ headers["Content-Type"] = contentType;
176
189
  }
177
190
  return axios.request({
178
191
  method: req.method,
@@ -234,4 +247,4 @@ const createHttpClient = (axios, opts) => {
234
247
  });
235
248
  };
236
249
 
237
- export { createHttpClient };
250
+ export { createHttpClient, noOpInterceptor, unwrap };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ps-aux/api-client-axios",
3
- "version": "0.7.0-rc.3",
3
+ "version": "0.7.0-rc.5",
4
4
  "main": "dist/node.cjs",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -15,10 +15,10 @@
15
15
  "author": "psaux",
16
16
  "license": "MIT",
17
17
  "peerDependencies": {
18
- "axios": "^1.13.5"
18
+ "axios": "^1.16.0"
19
19
  },
20
20
  "devDependencies": {
21
- "axios": "^1.5.0"
21
+ "axios": "^1.16.0"
22
22
  },
23
23
  "description": "Axios-based HTTP client for OpenAPI-generated APIs (Node and browser builds).",
24
24
  "keywords": [