make-service 0.0.3 → 0.2.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.
- package/README.md +43 -11
- package/dist/index.d.ts +29 -17
- package/dist/index.js +73 -33
- package/dist/index.mjs +71 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ Its [`typedResponse`](#typedresponse) can also be parsed with a zod schema. Here
|
|
|
76
76
|
```ts
|
|
77
77
|
const response = await api.get("/users", {
|
|
78
78
|
query: { search: "John" },
|
|
79
|
-
trace: (
|
|
79
|
+
trace: (url, requestInit) => console.log(url, requestInit),
|
|
80
80
|
})
|
|
81
81
|
const json = await response.json(
|
|
82
82
|
z.object({
|
|
@@ -104,6 +104,38 @@ await api.head("/users")
|
|
|
104
104
|
await api.options("/users")
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
This function can also correctly merge any sort of `URL`, `URLSearchParams`, and `Headers`.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { makeService } from 'make-service'
|
|
111
|
+
|
|
112
|
+
const api = makeService(new URL("https://example.com/api"), new Headers({
|
|
113
|
+
authorization: "Bearer 123"
|
|
114
|
+
}))
|
|
115
|
+
|
|
116
|
+
const response = await api.get("/users?admin=true", {
|
|
117
|
+
headers: [['accept', 'application/json']],
|
|
118
|
+
query: { page: "2" },
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
// It will call "https://example.com/api/users?admin=true&page=2"
|
|
122
|
+
// with headers: { authorization: "Bearer 123", accept: "application/json" }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
In case you want to delete a header previously set you can pass `undefined` or `'undefined'` as its value:
|
|
126
|
+
```ts
|
|
127
|
+
const api = makeService("https://example.com/api", { authorization: "Bearer 123" })
|
|
128
|
+
const response = await api.get("/users", {
|
|
129
|
+
headers: new Headers({ authorization: 'undefined', "Content-Type": undefined }),
|
|
130
|
+
})
|
|
131
|
+
// headers will be empty.
|
|
132
|
+
```
|
|
133
|
+
Note: Don't forget headers are case insensitive.
|
|
134
|
+
```ts
|
|
135
|
+
const headers = new Headers({ 'Content-Type': 'application/json' })
|
|
136
|
+
Object.fromEntries(headers) // equals to: { 'content-type': 'application/json' }
|
|
137
|
+
```
|
|
138
|
+
|
|
107
139
|
## enhancedFetch
|
|
108
140
|
|
|
109
141
|
A wrapper around the `fetch` API.
|
|
@@ -121,7 +153,7 @@ const json = await response.json()
|
|
|
121
153
|
// You can pass it a generic or schema to type the result
|
|
122
154
|
```
|
|
123
155
|
|
|
124
|
-
This function accepts the same arguments as the `fetch` API - with exception of [JSON-like body](/src/make-service.ts) -, and it also accepts an object-like [`query`](/src/make-service.ts) and a `trace` function that will be called with the `
|
|
156
|
+
This function accepts the same arguments as the `fetch` API - with exception of [JSON-like body](/src/make-service.ts) -, and it also accepts an object-like [`query`](/src/make-service.ts) and a `trace` function that will be called with the `url` and `requestInit` arguments.
|
|
125
157
|
|
|
126
158
|
This slightly different `RequestInit` is typed as `EnhancedRequestInit`.
|
|
127
159
|
|
|
@@ -132,7 +164,7 @@ await enhancedFetch("https://example.com/api/users", {
|
|
|
132
164
|
method: 'POST',
|
|
133
165
|
body: { some: { object: { as: { body } } } },
|
|
134
166
|
query: { page: "1" },
|
|
135
|
-
trace: (
|
|
167
|
+
trace: (url, requestInit) => console.log(url, requestInit)
|
|
136
168
|
})
|
|
137
169
|
|
|
138
170
|
// The trace function will be called with the following arguments:
|
|
@@ -155,21 +187,21 @@ import { typedResponse } from 'make-service'
|
|
|
155
187
|
import type { TypedResponse } from 'make-service'
|
|
156
188
|
|
|
157
189
|
// With JSON
|
|
158
|
-
const response: TypedResponse = new Response(JSON.stringify({ foo: "bar" }))
|
|
159
|
-
const json = await
|
|
190
|
+
const response: TypedResponse = typedResponse(new Response(JSON.stringify({ foo: "bar" })))
|
|
191
|
+
const json = await response.json()
|
|
160
192
|
// ^? unknown
|
|
161
|
-
const json = await
|
|
193
|
+
const json = await response.json<{ foo: string }>()
|
|
162
194
|
// ^? { foo: string }
|
|
163
|
-
const json = await
|
|
195
|
+
const json = await response.json(z.object({ foo: z.string() }))
|
|
164
196
|
// ^? { foo: string }
|
|
165
197
|
|
|
166
198
|
// With text
|
|
167
|
-
const response: TypedResponse = new Response("foo")
|
|
168
|
-
const text = await
|
|
199
|
+
const response: TypedResponse = typedResponse(new Response("foo"))
|
|
200
|
+
const text = await response.text()
|
|
169
201
|
// ^? string
|
|
170
|
-
const text = await
|
|
202
|
+
const text = await response.text<`foo${string}`>()
|
|
171
203
|
// ^? `foo${string}`
|
|
172
|
-
const text = await
|
|
204
|
+
const text = await response.text(z.string().email())
|
|
173
205
|
// ^? string
|
|
174
206
|
```
|
|
175
207
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const HTTP_METHODS: readonly ["
|
|
1
|
+
declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"];
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* It returns the JSON object or throws an error if the response is not ok.
|
|
@@ -26,24 +26,44 @@ type TypedResponse = Omit<Response, 'json' | 'text'> & {
|
|
|
26
26
|
type EnhancedRequestInit = Omit<RequestInit, 'body'> & {
|
|
27
27
|
body?: JSONValue;
|
|
28
28
|
query?: SearchParams;
|
|
29
|
+
params?: Record<string, string>;
|
|
29
30
|
trace?: (...args: Parameters<typeof fetch>) => void;
|
|
30
31
|
};
|
|
31
32
|
type ServiceRequestInit = Omit<EnhancedRequestInit, 'method'>;
|
|
32
33
|
type HTTPMethod = (typeof HTTP_METHODS)[number];
|
|
33
34
|
type TypedResponseJson = ReturnType<typeof getJson>;
|
|
34
35
|
type TypedResponseText = ReturnType<typeof getText>;
|
|
36
|
+
type Prettify<T> = {
|
|
37
|
+
[K in keyof T]: T[K];
|
|
38
|
+
} & {};
|
|
39
|
+
type NoEmpty<T> = keyof T extends never ? never : T;
|
|
40
|
+
type PathParams<T extends string> = NoEmpty<T extends `${infer _}:${infer Param}/${infer Rest}` ? Prettify<{
|
|
41
|
+
[K in Param]: string;
|
|
42
|
+
} & PathParams<Rest>> : T extends `${infer _}:${infer Param}` ? {
|
|
43
|
+
[K in Param]: string;
|
|
44
|
+
} : {}>;
|
|
35
45
|
|
|
36
46
|
/**
|
|
37
|
-
*
|
|
47
|
+
* It merges multiple HeadersInit objects into a single Headers object
|
|
48
|
+
* @param entries Any number of HeadersInit objects
|
|
49
|
+
* @returns a new Headers object with the merged headers
|
|
50
|
+
*/
|
|
51
|
+
declare function mergeHeaders(...entries: (HeadersInit | [string, undefined][] | Record<string, undefined>)[]): Headers;
|
|
52
|
+
/**
|
|
53
|
+
* @param url a string or URL to which the query parameters will be added
|
|
38
54
|
* @param searchParams the query parameters
|
|
39
|
-
* @returns the
|
|
55
|
+
* @returns the url with the query parameters added with the same type as the url
|
|
40
56
|
*/
|
|
41
|
-
declare function
|
|
57
|
+
declare function addQueryToUrl(url: string | URL, searchParams?: SearchParams): string | URL;
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated method renamed to addQueryToUrl
|
|
60
|
+
*/
|
|
61
|
+
declare const addQueryToInput: typeof addQueryToUrl;
|
|
42
62
|
/**
|
|
43
63
|
* @param baseURL the base path to the API
|
|
44
64
|
* @returns a function that receives a path and an object of query parameters and returns a URL
|
|
45
65
|
*/
|
|
46
|
-
declare function makeGetApiUrl(baseURL: string): (path: string, searchParams?: SearchParams) => string | URL;
|
|
66
|
+
declare function makeGetApiUrl(baseURL: string | URL): (path: string, searchParams?: SearchParams) => string | URL;
|
|
47
67
|
/**
|
|
48
68
|
* It hacks the Response object to add typed json and text methods
|
|
49
69
|
* @param response the Response to be proxied
|
|
@@ -66,7 +86,7 @@ declare function typedResponse(response: Response): TypedResponse;
|
|
|
66
86
|
declare function ensureStringBody(body?: JSONValue): string | undefined;
|
|
67
87
|
/**
|
|
68
88
|
*
|
|
69
|
-
* @param
|
|
89
|
+
* @param url a string or URL to be fetched
|
|
70
90
|
* @param requestInit the requestInit to be passed to the fetch request. It is the same as the `RequestInit` type, but it also accepts a JSON-like `body` and an object-like `query` parameter.
|
|
71
91
|
* @param requestInit.body the body of the request. It will be automatically stringified so you can send a JSON-like object
|
|
72
92
|
* @param requestInit.query the query parameters to be added to the URL
|
|
@@ -78,7 +98,7 @@ declare function ensureStringBody(body?: JSONValue): string | undefined;
|
|
|
78
98
|
* const untyped = await response.json();
|
|
79
99
|
* // ^? unknown
|
|
80
100
|
*/
|
|
81
|
-
declare function enhancedFetch(
|
|
101
|
+
declare function enhancedFetch(url: string | URL, requestInit?: EnhancedRequestInit): Promise<TypedResponse>;
|
|
82
102
|
/**
|
|
83
103
|
*
|
|
84
104
|
* @param baseURL the base URL to the API
|
|
@@ -90,14 +110,6 @@ declare function enhancedFetch(input: string | URL, requestInit?: EnhancedReques
|
|
|
90
110
|
* const users = await response.json(userSchema);
|
|
91
111
|
* // ^? User[]
|
|
92
112
|
*/
|
|
93
|
-
declare function makeService(baseURL: string, baseHeaders?: HeadersInit):
|
|
94
|
-
get: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
95
|
-
post: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
96
|
-
put: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
97
|
-
delete: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
98
|
-
patch: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
99
|
-
options: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
100
|
-
head: (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>;
|
|
101
|
-
};
|
|
113
|
+
declare function makeService(baseURL: string | URL, baseHeaders?: HeadersInit): Record<"delete" | "get" | "post" | "put" | "patch" | "options" | "head", (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>>;
|
|
102
114
|
|
|
103
|
-
export { EnhancedRequestInit, HTTPMethod, JSONValue, Schema, SearchParams, ServiceRequestInit, TypedResponse, TypedResponseJson, TypedResponseText, addQueryToInput, enhancedFetch, ensureStringBody, makeGetApiUrl, makeService, typedResponse };
|
|
115
|
+
export { EnhancedRequestInit, HTTPMethod, JSONValue, PathParams, Schema, SearchParams, ServiceRequestInit, TypedResponse, TypedResponseJson, TypedResponseText, addQueryToInput, addQueryToUrl, enhancedFetch, ensureStringBody, makeGetApiUrl, makeService, mergeHeaders, typedResponse };
|
package/dist/index.js
CHANGED
|
@@ -21,23 +21,25 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
addQueryToInput: () => addQueryToInput,
|
|
24
|
+
addQueryToUrl: () => addQueryToUrl,
|
|
24
25
|
enhancedFetch: () => enhancedFetch,
|
|
25
26
|
ensureStringBody: () => ensureStringBody,
|
|
26
27
|
makeGetApiUrl: () => makeGetApiUrl,
|
|
27
28
|
makeService: () => makeService,
|
|
29
|
+
mergeHeaders: () => mergeHeaders,
|
|
28
30
|
typedResponse: () => typedResponse
|
|
29
31
|
});
|
|
30
32
|
module.exports = __toCommonJS(src_exports);
|
|
31
33
|
|
|
32
34
|
// src/constants.ts
|
|
33
35
|
var HTTP_METHODS = [
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
36
|
+
"GET",
|
|
37
|
+
"POST",
|
|
38
|
+
"PUT",
|
|
39
|
+
"DELETE",
|
|
40
|
+
"PATCH",
|
|
41
|
+
"OPTIONS",
|
|
42
|
+
"HEAD"
|
|
41
43
|
];
|
|
42
44
|
|
|
43
45
|
// src/internals.ts
|
|
@@ -56,25 +58,54 @@ function getText(response) {
|
|
|
56
58
|
return schema ? schema.parse(text) : text;
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
+
function replaceUrlParams(url, params) {
|
|
62
|
+
if (!params)
|
|
63
|
+
return url;
|
|
64
|
+
let urlString = String(url);
|
|
65
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
66
|
+
urlString = urlString.replace(new RegExp(`:${key}($|/)`), `${value}$1`);
|
|
67
|
+
});
|
|
68
|
+
return url instanceof URL ? new URL(urlString) : urlString;
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
// src/make-service.ts
|
|
64
|
-
function
|
|
72
|
+
function mergeHeaders(...entries) {
|
|
73
|
+
const result = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const headers = new Headers(entry);
|
|
76
|
+
for (const [key, value] of headers.entries()) {
|
|
77
|
+
if (value === void 0 || value === "undefined") {
|
|
78
|
+
result.delete(key);
|
|
79
|
+
} else {
|
|
80
|
+
result.set(key, value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return new Headers(Array.from(result.entries()));
|
|
85
|
+
}
|
|
86
|
+
function addQueryToUrl(url, searchParams) {
|
|
65
87
|
if (!searchParams)
|
|
66
|
-
return
|
|
67
|
-
if (
|
|
68
|
-
const separator =
|
|
69
|
-
return `${
|
|
88
|
+
return url;
|
|
89
|
+
if (typeof url === "string") {
|
|
90
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
91
|
+
return `${url}${separator}${new URLSearchParams(searchParams)}`;
|
|
70
92
|
}
|
|
71
|
-
if (searchParams &&
|
|
72
|
-
|
|
93
|
+
if (searchParams && url instanceof URL) {
|
|
94
|
+
for (const [key, value] of Object.entries(
|
|
95
|
+
new URLSearchParams(searchParams)
|
|
96
|
+
)) {
|
|
97
|
+
url.searchParams.set(key, value);
|
|
98
|
+
}
|
|
73
99
|
}
|
|
74
|
-
return
|
|
100
|
+
return url;
|
|
75
101
|
}
|
|
102
|
+
var addQueryToInput = addQueryToUrl;
|
|
76
103
|
function makeGetApiUrl(baseURL) {
|
|
77
|
-
|
|
104
|
+
const base = baseURL instanceof URL ? baseURL.toString() : baseURL;
|
|
105
|
+
return (path, searchParams) => {
|
|
106
|
+
const url = `${base}${path}`.replace(/([^https?:]\/)\/+/g, "$1");
|
|
107
|
+
return addQueryToUrl(url, searchParams);
|
|
108
|
+
};
|
|
78
109
|
}
|
|
79
110
|
function typedResponse(response) {
|
|
80
111
|
return new Proxy(response, {
|
|
@@ -94,42 +125,51 @@ function ensureStringBody(body) {
|
|
|
94
125
|
return body;
|
|
95
126
|
return JSON.stringify(body);
|
|
96
127
|
}
|
|
97
|
-
async function enhancedFetch(
|
|
128
|
+
async function enhancedFetch(url, requestInit) {
|
|
129
|
+
var _a, _b;
|
|
98
130
|
const { query, trace, ...reqInit } = requestInit != null ? requestInit : {};
|
|
99
|
-
const headers =
|
|
100
|
-
|
|
131
|
+
const headers = mergeHeaders(
|
|
132
|
+
{
|
|
133
|
+
"content-type": "application/json"
|
|
134
|
+
},
|
|
135
|
+
(_a = reqInit.headers) != null ? _a : {}
|
|
136
|
+
);
|
|
137
|
+
const withParams = replaceUrlParams(url, (_b = reqInit.params) != null ? _b : {});
|
|
138
|
+
const fullUrl = addQueryToUrl(withParams, query);
|
|
101
139
|
const body = ensureStringBody(reqInit.body);
|
|
102
140
|
const enhancedReqInit = { ...reqInit, headers, body };
|
|
103
|
-
trace == null ? void 0 : trace(
|
|
104
|
-
const
|
|
105
|
-
const response = await fetch(request);
|
|
141
|
+
trace == null ? void 0 : trace(fullUrl, enhancedReqInit);
|
|
142
|
+
const response = await fetch(fullUrl, enhancedReqInit);
|
|
106
143
|
return typedResponse(response);
|
|
107
144
|
}
|
|
108
145
|
function makeService(baseURL, baseHeaders) {
|
|
109
146
|
const service = (method) => {
|
|
110
147
|
return async (path, requestInit = {}) => {
|
|
111
|
-
|
|
148
|
+
var _a;
|
|
149
|
+
const url = makeGetApiUrl(baseURL)(path);
|
|
150
|
+
const response = await enhancedFetch(url, {
|
|
112
151
|
...requestInit,
|
|
113
152
|
method,
|
|
114
|
-
headers:
|
|
153
|
+
headers: mergeHeaders(baseHeaders != null ? baseHeaders : {}, (_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {})
|
|
115
154
|
});
|
|
116
155
|
return response;
|
|
117
156
|
};
|
|
118
157
|
};
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
158
|
+
let api = {};
|
|
159
|
+
for (const method of HTTP_METHODS) {
|
|
160
|
+
const lowerMethod = method.toLowerCase();
|
|
161
|
+
api[lowerMethod] = service(method);
|
|
162
|
+
}
|
|
163
|
+
return api;
|
|
126
164
|
}
|
|
127
165
|
// Annotate the CommonJS export names for ESM import in node:
|
|
128
166
|
0 && (module.exports = {
|
|
129
167
|
addQueryToInput,
|
|
168
|
+
addQueryToUrl,
|
|
130
169
|
enhancedFetch,
|
|
131
170
|
ensureStringBody,
|
|
132
171
|
makeGetApiUrl,
|
|
133
172
|
makeService,
|
|
173
|
+
mergeHeaders,
|
|
134
174
|
typedResponse
|
|
135
175
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
2
|
var HTTP_METHODS = [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
3
|
+
"GET",
|
|
4
|
+
"POST",
|
|
5
|
+
"PUT",
|
|
6
|
+
"DELETE",
|
|
7
|
+
"PATCH",
|
|
8
|
+
"OPTIONS",
|
|
9
|
+
"HEAD"
|
|
10
10
|
];
|
|
11
11
|
|
|
12
12
|
// src/internals.ts
|
|
@@ -25,25 +25,54 @@ function getText(response) {
|
|
|
25
25
|
return schema ? schema.parse(text) : text;
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
28
|
+
function replaceUrlParams(url, params) {
|
|
29
|
+
if (!params)
|
|
30
|
+
return url;
|
|
31
|
+
let urlString = String(url);
|
|
32
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
33
|
+
urlString = urlString.replace(new RegExp(`:${key}($|/)`), `${value}$1`);
|
|
34
|
+
});
|
|
35
|
+
return url instanceof URL ? new URL(urlString) : urlString;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
// src/make-service.ts
|
|
33
|
-
function
|
|
39
|
+
function mergeHeaders(...entries) {
|
|
40
|
+
const result = /* @__PURE__ */ new Map();
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
const headers = new Headers(entry);
|
|
43
|
+
for (const [key, value] of headers.entries()) {
|
|
44
|
+
if (value === void 0 || value === "undefined") {
|
|
45
|
+
result.delete(key);
|
|
46
|
+
} else {
|
|
47
|
+
result.set(key, value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return new Headers(Array.from(result.entries()));
|
|
52
|
+
}
|
|
53
|
+
function addQueryToUrl(url, searchParams) {
|
|
34
54
|
if (!searchParams)
|
|
35
|
-
return
|
|
36
|
-
if (
|
|
37
|
-
const separator =
|
|
38
|
-
return `${
|
|
55
|
+
return url;
|
|
56
|
+
if (typeof url === "string") {
|
|
57
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
58
|
+
return `${url}${separator}${new URLSearchParams(searchParams)}`;
|
|
39
59
|
}
|
|
40
|
-
if (searchParams &&
|
|
41
|
-
|
|
60
|
+
if (searchParams && url instanceof URL) {
|
|
61
|
+
for (const [key, value] of Object.entries(
|
|
62
|
+
new URLSearchParams(searchParams)
|
|
63
|
+
)) {
|
|
64
|
+
url.searchParams.set(key, value);
|
|
65
|
+
}
|
|
42
66
|
}
|
|
43
|
-
return
|
|
67
|
+
return url;
|
|
44
68
|
}
|
|
69
|
+
var addQueryToInput = addQueryToUrl;
|
|
45
70
|
function makeGetApiUrl(baseURL) {
|
|
46
|
-
|
|
71
|
+
const base = baseURL instanceof URL ? baseURL.toString() : baseURL;
|
|
72
|
+
return (path, searchParams) => {
|
|
73
|
+
const url = `${base}${path}`.replace(/([^https?:]\/)\/+/g, "$1");
|
|
74
|
+
return addQueryToUrl(url, searchParams);
|
|
75
|
+
};
|
|
47
76
|
}
|
|
48
77
|
function typedResponse(response) {
|
|
49
78
|
return new Proxy(response, {
|
|
@@ -63,41 +92,50 @@ function ensureStringBody(body) {
|
|
|
63
92
|
return body;
|
|
64
93
|
return JSON.stringify(body);
|
|
65
94
|
}
|
|
66
|
-
async function enhancedFetch(
|
|
95
|
+
async function enhancedFetch(url, requestInit) {
|
|
96
|
+
var _a, _b;
|
|
67
97
|
const { query, trace, ...reqInit } = requestInit != null ? requestInit : {};
|
|
68
|
-
const headers =
|
|
69
|
-
|
|
98
|
+
const headers = mergeHeaders(
|
|
99
|
+
{
|
|
100
|
+
"content-type": "application/json"
|
|
101
|
+
},
|
|
102
|
+
(_a = reqInit.headers) != null ? _a : {}
|
|
103
|
+
);
|
|
104
|
+
const withParams = replaceUrlParams(url, (_b = reqInit.params) != null ? _b : {});
|
|
105
|
+
const fullUrl = addQueryToUrl(withParams, query);
|
|
70
106
|
const body = ensureStringBody(reqInit.body);
|
|
71
107
|
const enhancedReqInit = { ...reqInit, headers, body };
|
|
72
|
-
trace == null ? void 0 : trace(
|
|
73
|
-
const
|
|
74
|
-
const response = await fetch(request);
|
|
108
|
+
trace == null ? void 0 : trace(fullUrl, enhancedReqInit);
|
|
109
|
+
const response = await fetch(fullUrl, enhancedReqInit);
|
|
75
110
|
return typedResponse(response);
|
|
76
111
|
}
|
|
77
112
|
function makeService(baseURL, baseHeaders) {
|
|
78
113
|
const service = (method) => {
|
|
79
114
|
return async (path, requestInit = {}) => {
|
|
80
|
-
|
|
115
|
+
var _a;
|
|
116
|
+
const url = makeGetApiUrl(baseURL)(path);
|
|
117
|
+
const response = await enhancedFetch(url, {
|
|
81
118
|
...requestInit,
|
|
82
119
|
method,
|
|
83
|
-
headers:
|
|
120
|
+
headers: mergeHeaders(baseHeaders != null ? baseHeaders : {}, (_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {})
|
|
84
121
|
});
|
|
85
122
|
return response;
|
|
86
123
|
};
|
|
87
124
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
125
|
+
let api = {};
|
|
126
|
+
for (const method of HTTP_METHODS) {
|
|
127
|
+
const lowerMethod = method.toLowerCase();
|
|
128
|
+
api[lowerMethod] = service(method);
|
|
129
|
+
}
|
|
130
|
+
return api;
|
|
95
131
|
}
|
|
96
132
|
export {
|
|
97
133
|
addQueryToInput,
|
|
134
|
+
addQueryToUrl,
|
|
98
135
|
enhancedFetch,
|
|
99
136
|
ensureStringBody,
|
|
100
137
|
makeGetApiUrl,
|
|
101
138
|
makeService,
|
|
139
|
+
mergeHeaders,
|
|
102
140
|
typedResponse
|
|
103
141
|
};
|