@firtoz/hono-fetcher 2.3.2 → 2.4.1
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/package.json +7 -7
- package/src/honoFetcher.ts +53 -4
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firtoz/hono-fetcher",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "Type-safe Hono API client with full TypeScript inference for routes, params, and payloads",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"typecheck": "
|
|
26
|
+
"typecheck": "tsgo --noEmit -p ./tsconfig.json",
|
|
27
27
|
"lint": "biome check --write src",
|
|
28
28
|
"lint:ci": "biome ci src",
|
|
29
29
|
"format": "biome format src --write",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"url": "https://github.com/firtoz/fullstack-toolkit/issues"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@cloudflare/workers-types": "^4.
|
|
56
|
-
"hono": "^4.
|
|
55
|
+
"@cloudflare/workers-types": "^4.20260329.1",
|
|
56
|
+
"hono": "^4.12.9"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=18.0.0"
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@hono/node-server": "^1.19.
|
|
65
|
+
"@hono/node-server": "^1.19.11",
|
|
66
66
|
"@hono/zod-validator": "^0.7.6",
|
|
67
|
-
"bun-types": "^1.3.
|
|
68
|
-
"zod": "^4.3.
|
|
67
|
+
"bun-types": "^1.3.11",
|
|
68
|
+
"zod": "^4.3.6"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/src/honoFetcher.ts
CHANGED
|
@@ -33,14 +33,59 @@ type HasPathParams<T extends string> = T extends `${string}:${string}`
|
|
|
33
33
|
? true
|
|
34
34
|
: false;
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Values allowed in the optional `query` object on fetcher requests.
|
|
38
|
+
* `null` and `undefined` entries are omitted from the serialized query string.
|
|
39
|
+
*/
|
|
40
|
+
export type HonoFetcherQueryParamValue = string | number | boolean;
|
|
41
|
+
|
|
42
|
+
export type HonoFetcherQueryParams = Record<
|
|
43
|
+
string,
|
|
44
|
+
HonoFetcherQueryParamValue | null | undefined
|
|
45
|
+
>;
|
|
46
|
+
|
|
47
|
+
function appendQueryString(
|
|
48
|
+
url: string,
|
|
49
|
+
query?: HonoFetcherQueryParams,
|
|
50
|
+
): string {
|
|
51
|
+
if (!query) {
|
|
52
|
+
return url;
|
|
53
|
+
}
|
|
54
|
+
const searchParams = new URLSearchParams();
|
|
55
|
+
for (const [key, value] of Object.entries(query)) {
|
|
56
|
+
if (value === undefined || value === null) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
searchParams.append(key, String(value));
|
|
60
|
+
}
|
|
61
|
+
const serialized = searchParams.toString();
|
|
62
|
+
if (!serialized) {
|
|
63
|
+
return url;
|
|
64
|
+
}
|
|
65
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
66
|
+
return `${url}${separator}${serialized}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* `RequestInit` fields that honoFetcher sets must not be overwritten by spreading `...init` last.
|
|
71
|
+
*/
|
|
72
|
+
function restOfRequestInit(
|
|
73
|
+
init: RequestInit,
|
|
74
|
+
): Omit<RequestInit, "headers" | "body" | "method"> {
|
|
75
|
+
const { headers: _h, body: _b, method: _m, ...rest } = init;
|
|
76
|
+
return rest;
|
|
77
|
+
}
|
|
78
|
+
|
|
36
79
|
type FetcherParams<SchemaPath extends string> =
|
|
37
80
|
HasPathParams<SchemaPath> extends true
|
|
38
81
|
? {
|
|
39
82
|
params: ParsePathParams<SchemaPath>;
|
|
83
|
+
query?: HonoFetcherQueryParams;
|
|
40
84
|
init?: RequestInit;
|
|
41
85
|
}
|
|
42
86
|
: {
|
|
43
87
|
params?: never;
|
|
88
|
+
query?: HonoFetcherQueryParams;
|
|
44
89
|
init?: RequestInit;
|
|
45
90
|
};
|
|
46
91
|
|
|
@@ -136,7 +181,7 @@ const createMethodFetcher = <T extends Hono, M extends HttpMethod>(
|
|
|
136
181
|
return (async (request) => {
|
|
137
182
|
let finalUrl: string = request.url;
|
|
138
183
|
|
|
139
|
-
const { init = {}, params } = request;
|
|
184
|
+
const { init = {}, params, query } = request;
|
|
140
185
|
|
|
141
186
|
if (params && typeof params === "object") {
|
|
142
187
|
finalUrl = Object.entries(params).reduce((acc, [key, value]) => {
|
|
@@ -144,6 +189,8 @@ const createMethodFetcher = <T extends Hono, M extends HttpMethod>(
|
|
|
144
189
|
}, finalUrl);
|
|
145
190
|
}
|
|
146
191
|
|
|
192
|
+
finalUrl = appendQueryString(finalUrl, query);
|
|
193
|
+
|
|
147
194
|
const requestAsOptionalFormBody = request as {
|
|
148
195
|
form?: unknown;
|
|
149
196
|
body?: unknown;
|
|
@@ -172,10 +219,10 @@ const createMethodFetcher = <T extends Hono, M extends HttpMethod>(
|
|
|
172
219
|
|
|
173
220
|
try {
|
|
174
221
|
return await fetcher(finalUrl, {
|
|
222
|
+
...restOfRequestInit(init),
|
|
175
223
|
method: method.toUpperCase(),
|
|
176
224
|
headers: newHeaders,
|
|
177
225
|
...(body ? { body } : {}),
|
|
178
|
-
...init,
|
|
179
226
|
});
|
|
180
227
|
} catch (error) {
|
|
181
228
|
console.error(`Error ${method}ing`, error);
|
|
@@ -193,7 +240,7 @@ const createWebSocketFetcher = <T extends Hono>(
|
|
|
193
240
|
return (async (request) => {
|
|
194
241
|
let finalUrl: string = request.url;
|
|
195
242
|
|
|
196
|
-
const { init = {}, params, config } = request;
|
|
243
|
+
const { init = {}, params, query, config } = request;
|
|
197
244
|
const autoAccept = config?.autoAccept ?? true; // Default to true
|
|
198
245
|
|
|
199
246
|
if (params && typeof params === "object") {
|
|
@@ -202,6 +249,8 @@ const createWebSocketFetcher = <T extends Hono>(
|
|
|
202
249
|
}, finalUrl);
|
|
203
250
|
}
|
|
204
251
|
|
|
252
|
+
finalUrl = appendQueryString(finalUrl, query);
|
|
253
|
+
|
|
205
254
|
const newHeaders = new Headers(
|
|
206
255
|
init.headers as unknown as ConstructorParameters<typeof Headers>[0],
|
|
207
256
|
);
|
|
@@ -209,9 +258,9 @@ const createWebSocketFetcher = <T extends Hono>(
|
|
|
209
258
|
|
|
210
259
|
try {
|
|
211
260
|
const response = await fetcher(finalUrl, {
|
|
261
|
+
...restOfRequestInit(init),
|
|
212
262
|
method: "GET",
|
|
213
263
|
headers: newHeaders,
|
|
214
|
-
...init,
|
|
215
264
|
});
|
|
216
265
|
|
|
217
266
|
// Auto-accept the WebSocket if configured (default: true)
|