make-service 0.2.0 → 1.0.0-next.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 +5 -3
- package/dist/index.d.ts +5 -9
- package/dist/index.js +9 -9
- package/dist/index.mjs +9 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ It adds a set of little features and allows you to parse responses with [zod](ht
|
|
|
8
8
|
- 🤩 Type-safe return of `response.json()` and `response.text()`. Defaults to `unknown` instead of `any`.
|
|
9
9
|
- 🚦 Easily setup an API with a `baseURL` and common `headers` for every request.
|
|
10
10
|
- 🏗️ Compose URL from the base by just calling the endpoints and an object-like `query`.
|
|
11
|
+
- 🐾 Replaces URL wildcards with an object of `params`.
|
|
11
12
|
- 🧙♀️ Automatically stringifies the `body` of a request so you can give it a JSON-like structure.
|
|
12
13
|
- 🐛 Accepts a `trace` function for debugging.
|
|
13
14
|
|
|
@@ -153,22 +154,23 @@ const json = await response.json()
|
|
|
153
154
|
// You can pass it a generic or schema to type the result
|
|
154
155
|
```
|
|
155
156
|
|
|
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.
|
|
157
|
+
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 of `params` to replace URL wildcards, an object-like [`query`](/src/make-service.ts) and a `trace` function that will be called with the `url` and `requestInit` arguments.
|
|
157
158
|
|
|
158
159
|
This slightly different `RequestInit` is typed as `EnhancedRequestInit`.
|
|
159
160
|
|
|
160
161
|
```ts
|
|
161
162
|
import { enhancedFetch } from 'make-service'
|
|
162
163
|
|
|
163
|
-
await enhancedFetch("https://example.com/api/users", {
|
|
164
|
+
await enhancedFetch("https://example.com/api/users/:role", {
|
|
164
165
|
method: 'POST',
|
|
165
166
|
body: { some: { object: { as: { body } } } },
|
|
166
167
|
query: { page: "1" },
|
|
168
|
+
params: { role: "admin" },
|
|
167
169
|
trace: (url, requestInit) => console.log(url, requestInit)
|
|
168
170
|
})
|
|
169
171
|
|
|
170
172
|
// The trace function will be called with the following arguments:
|
|
171
|
-
// "https://example.com/api/users?page=1"
|
|
173
|
+
// "https://example.com/api/users/admin?page=1"
|
|
172
174
|
// {
|
|
173
175
|
// method: 'POST',
|
|
174
176
|
// body: '{"some":{"object":{"as":{"body":{}}}}}',
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ type TypedResponse = Omit<Response, 'json' | 'text'> & {
|
|
|
24
24
|
text: TypedResponseText;
|
|
25
25
|
};
|
|
26
26
|
type EnhancedRequestInit = Omit<RequestInit, 'body'> & {
|
|
27
|
-
body?: JSONValue;
|
|
27
|
+
body?: JSONValue | BodyInit | null;
|
|
28
28
|
query?: SearchParams;
|
|
29
29
|
params?: Record<string, string>;
|
|
30
30
|
trace?: (...args: Parameters<typeof fetch>) => void;
|
|
@@ -55,10 +55,6 @@ declare function mergeHeaders(...entries: (HeadersInit | [string, undefined][] |
|
|
|
55
55
|
* @returns the url with the query parameters added with the same type as the url
|
|
56
56
|
*/
|
|
57
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;
|
|
62
58
|
/**
|
|
63
59
|
* @param baseURL the base path to the API
|
|
64
60
|
* @returns a function that receives a path and an object of query parameters and returns a URL
|
|
@@ -81,9 +77,9 @@ declare function makeGetApiUrl(baseURL: string | URL): (path: string, searchPara
|
|
|
81
77
|
declare function typedResponse(response: Response): TypedResponse;
|
|
82
78
|
/**
|
|
83
79
|
* @param body the JSON-like body of the request
|
|
84
|
-
* @returns the body stringified if it is not a string
|
|
80
|
+
* @returns the body is stringified if it is not a string and it is a JSON-like object. It also accepts other types of BodyInit such as Blob, ReadableStream, etc.
|
|
85
81
|
*/
|
|
86
|
-
declare function ensureStringBody(body?:
|
|
82
|
+
declare function ensureStringBody<B extends JSONValue | BodyInit | null>(body?: B): B extends JSONValue ? string : B;
|
|
87
83
|
/**
|
|
88
84
|
*
|
|
89
85
|
* @param url a string or URL to be fetched
|
|
@@ -110,6 +106,6 @@ declare function enhancedFetch(url: string | URL, requestInit?: EnhancedRequestI
|
|
|
110
106
|
* const users = await response.json(userSchema);
|
|
111
107
|
* // ^? User[]
|
|
112
108
|
*/
|
|
113
|
-
declare function makeService(baseURL: string | URL, baseHeaders?: HeadersInit): Record<"delete" | "get" | "post" | "put" | "patch" | "options" | "head", (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>>;
|
|
109
|
+
declare function makeService(baseURL: string | URL, baseHeaders?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>)): Record<"delete" | "get" | "post" | "put" | "patch" | "options" | "head", (path: string, requestInit?: ServiceRequestInit) => Promise<TypedResponse>>;
|
|
114
110
|
|
|
115
|
-
export { EnhancedRequestInit, HTTPMethod, JSONValue, PathParams, Schema, SearchParams, ServiceRequestInit, TypedResponse, TypedResponseJson, TypedResponseText,
|
|
111
|
+
export { EnhancedRequestInit, HTTPMethod, JSONValue, PathParams, Schema, SearchParams, ServiceRequestInit, TypedResponse, TypedResponseJson, TypedResponseText, addQueryToUrl, enhancedFetch, ensureStringBody, makeGetApiUrl, makeService, mergeHeaders, typedResponse };
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
addQueryToInput: () => addQueryToInput,
|
|
24
23
|
addQueryToUrl: () => addQueryToUrl,
|
|
25
24
|
enhancedFetch: () => enhancedFetch,
|
|
26
25
|
ensureStringBody: () => ensureStringBody,
|
|
@@ -45,9 +44,6 @@ var HTTP_METHODS = [
|
|
|
45
44
|
// src/internals.ts
|
|
46
45
|
function getJson(response) {
|
|
47
46
|
return async (schema) => {
|
|
48
|
-
if (!response.ok) {
|
|
49
|
-
throw new Error(await response.text());
|
|
50
|
-
}
|
|
51
47
|
const json = await response.json();
|
|
52
48
|
return schema ? schema.parse(json) : json;
|
|
53
49
|
};
|
|
@@ -67,6 +63,9 @@ function replaceUrlParams(url, params) {
|
|
|
67
63
|
});
|
|
68
64
|
return url instanceof URL ? new URL(urlString) : urlString;
|
|
69
65
|
}
|
|
66
|
+
function typeOf(t) {
|
|
67
|
+
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
68
|
+
}
|
|
70
69
|
|
|
71
70
|
// src/make-service.ts
|
|
72
71
|
function mergeHeaders(...entries) {
|
|
@@ -99,7 +98,6 @@ function addQueryToUrl(url, searchParams) {
|
|
|
99
98
|
}
|
|
100
99
|
return url;
|
|
101
100
|
}
|
|
102
|
-
var addQueryToInput = addQueryToUrl;
|
|
103
101
|
function makeGetApiUrl(baseURL) {
|
|
104
102
|
const base = baseURL instanceof URL ? baseURL.toString() : baseURL;
|
|
105
103
|
return (path, searchParams) => {
|
|
@@ -120,10 +118,10 @@ function typedResponse(response) {
|
|
|
120
118
|
}
|
|
121
119
|
function ensureStringBody(body) {
|
|
122
120
|
if (typeof body === "undefined")
|
|
123
|
-
return;
|
|
121
|
+
return body;
|
|
124
122
|
if (typeof body === "string")
|
|
125
123
|
return body;
|
|
126
|
-
return JSON.stringify(body);
|
|
124
|
+
return ["number", "boolean", "array", "object"].includes(typeOf(body)) ? JSON.stringify(body) : body;
|
|
127
125
|
}
|
|
128
126
|
async function enhancedFetch(url, requestInit) {
|
|
129
127
|
var _a, _b;
|
|
@@ -150,7 +148,10 @@ function makeService(baseURL, baseHeaders) {
|
|
|
150
148
|
const response = await enhancedFetch(url, {
|
|
151
149
|
...requestInit,
|
|
152
150
|
method,
|
|
153
|
-
headers: mergeHeaders(
|
|
151
|
+
headers: mergeHeaders(
|
|
152
|
+
typeof baseHeaders === "function" ? await baseHeaders() : baseHeaders != null ? baseHeaders : {},
|
|
153
|
+
(_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {}
|
|
154
|
+
)
|
|
154
155
|
});
|
|
155
156
|
return response;
|
|
156
157
|
};
|
|
@@ -164,7 +165,6 @@ function makeService(baseURL, baseHeaders) {
|
|
|
164
165
|
}
|
|
165
166
|
// Annotate the CommonJS export names for ESM import in node:
|
|
166
167
|
0 && (module.exports = {
|
|
167
|
-
addQueryToInput,
|
|
168
168
|
addQueryToUrl,
|
|
169
169
|
enhancedFetch,
|
|
170
170
|
ensureStringBody,
|
package/dist/index.mjs
CHANGED
|
@@ -12,9 +12,6 @@ var HTTP_METHODS = [
|
|
|
12
12
|
// src/internals.ts
|
|
13
13
|
function getJson(response) {
|
|
14
14
|
return async (schema) => {
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw new Error(await response.text());
|
|
17
|
-
}
|
|
18
15
|
const json = await response.json();
|
|
19
16
|
return schema ? schema.parse(json) : json;
|
|
20
17
|
};
|
|
@@ -34,6 +31,9 @@ function replaceUrlParams(url, params) {
|
|
|
34
31
|
});
|
|
35
32
|
return url instanceof URL ? new URL(urlString) : urlString;
|
|
36
33
|
}
|
|
34
|
+
function typeOf(t) {
|
|
35
|
+
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
36
|
+
}
|
|
37
37
|
|
|
38
38
|
// src/make-service.ts
|
|
39
39
|
function mergeHeaders(...entries) {
|
|
@@ -66,7 +66,6 @@ function addQueryToUrl(url, searchParams) {
|
|
|
66
66
|
}
|
|
67
67
|
return url;
|
|
68
68
|
}
|
|
69
|
-
var addQueryToInput = addQueryToUrl;
|
|
70
69
|
function makeGetApiUrl(baseURL) {
|
|
71
70
|
const base = baseURL instanceof URL ? baseURL.toString() : baseURL;
|
|
72
71
|
return (path, searchParams) => {
|
|
@@ -87,10 +86,10 @@ function typedResponse(response) {
|
|
|
87
86
|
}
|
|
88
87
|
function ensureStringBody(body) {
|
|
89
88
|
if (typeof body === "undefined")
|
|
90
|
-
return;
|
|
89
|
+
return body;
|
|
91
90
|
if (typeof body === "string")
|
|
92
91
|
return body;
|
|
93
|
-
return JSON.stringify(body);
|
|
92
|
+
return ["number", "boolean", "array", "object"].includes(typeOf(body)) ? JSON.stringify(body) : body;
|
|
94
93
|
}
|
|
95
94
|
async function enhancedFetch(url, requestInit) {
|
|
96
95
|
var _a, _b;
|
|
@@ -117,7 +116,10 @@ function makeService(baseURL, baseHeaders) {
|
|
|
117
116
|
const response = await enhancedFetch(url, {
|
|
118
117
|
...requestInit,
|
|
119
118
|
method,
|
|
120
|
-
headers: mergeHeaders(
|
|
119
|
+
headers: mergeHeaders(
|
|
120
|
+
typeof baseHeaders === "function" ? await baseHeaders() : baseHeaders != null ? baseHeaders : {},
|
|
121
|
+
(_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {}
|
|
122
|
+
)
|
|
121
123
|
});
|
|
122
124
|
return response;
|
|
123
125
|
};
|
|
@@ -130,7 +132,6 @@ function makeService(baseURL, baseHeaders) {
|
|
|
130
132
|
return api;
|
|
131
133
|
}
|
|
132
134
|
export {
|
|
133
|
-
addQueryToInput,
|
|
134
135
|
addQueryToUrl,
|
|
135
136
|
enhancedFetch,
|
|
136
137
|
ensureStringBody,
|
package/package.json
CHANGED