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 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?: JSONValue): string | undefined;
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, addQueryToInput, addQueryToUrl, enhancedFetch, ensureStringBody, makeGetApiUrl, makeService, mergeHeaders, typedResponse };
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(baseHeaders != null ? baseHeaders : {}, (_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {})
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(baseHeaders != null ? baseHeaders : {}, (_a = requestInit == null ? void 0 : requestInit.headers) != null ? _a : {})
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "make-service",
3
- "version": "0.2.0",
3
+ "version": "1.0.0-next.0",
4
4
  "description": "Some utilities to extend the 'fetch' API to better interact with external APIs.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",