@firtoz/hono-fetcher 2.3.2 → 2.4.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/package.json +7 -7
- package/src/honoFetcher.ts +41 -2
- 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.0",
|
|
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,49 @@ 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
|
+
|
|
36
69
|
type FetcherParams<SchemaPath extends string> =
|
|
37
70
|
HasPathParams<SchemaPath> extends true
|
|
38
71
|
? {
|
|
39
72
|
params: ParsePathParams<SchemaPath>;
|
|
73
|
+
query?: HonoFetcherQueryParams;
|
|
40
74
|
init?: RequestInit;
|
|
41
75
|
}
|
|
42
76
|
: {
|
|
43
77
|
params?: never;
|
|
78
|
+
query?: HonoFetcherQueryParams;
|
|
44
79
|
init?: RequestInit;
|
|
45
80
|
};
|
|
46
81
|
|
|
@@ -136,7 +171,7 @@ const createMethodFetcher = <T extends Hono, M extends HttpMethod>(
|
|
|
136
171
|
return (async (request) => {
|
|
137
172
|
let finalUrl: string = request.url;
|
|
138
173
|
|
|
139
|
-
const { init = {}, params } = request;
|
|
174
|
+
const { init = {}, params, query } = request;
|
|
140
175
|
|
|
141
176
|
if (params && typeof params === "object") {
|
|
142
177
|
finalUrl = Object.entries(params).reduce((acc, [key, value]) => {
|
|
@@ -144,6 +179,8 @@ const createMethodFetcher = <T extends Hono, M extends HttpMethod>(
|
|
|
144
179
|
}, finalUrl);
|
|
145
180
|
}
|
|
146
181
|
|
|
182
|
+
finalUrl = appendQueryString(finalUrl, query);
|
|
183
|
+
|
|
147
184
|
const requestAsOptionalFormBody = request as {
|
|
148
185
|
form?: unknown;
|
|
149
186
|
body?: unknown;
|
|
@@ -193,7 +230,7 @@ const createWebSocketFetcher = <T extends Hono>(
|
|
|
193
230
|
return (async (request) => {
|
|
194
231
|
let finalUrl: string = request.url;
|
|
195
232
|
|
|
196
|
-
const { init = {}, params, config } = request;
|
|
233
|
+
const { init = {}, params, query, config } = request;
|
|
197
234
|
const autoAccept = config?.autoAccept ?? true; // Default to true
|
|
198
235
|
|
|
199
236
|
if (params && typeof params === "object") {
|
|
@@ -202,6 +239,8 @@ const createWebSocketFetcher = <T extends Hono>(
|
|
|
202
239
|
}, finalUrl);
|
|
203
240
|
}
|
|
204
241
|
|
|
242
|
+
finalUrl = appendQueryString(finalUrl, query);
|
|
243
|
+
|
|
205
244
|
const newHeaders = new Headers(
|
|
206
245
|
init.headers as unknown as ConstructorParameters<typeof Headers>[0],
|
|
207
246
|
);
|