@zap-studio/fetch 0.4.6 → 0.5.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/CHANGELOG.md +45 -1
- package/{LICENSE.md → LICENSE} +1 -1
- package/README.md +276 -32
- package/dist/constants.d.mts +8 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +9 -2
- package/dist/constants.mjs.map +1 -1
- package/dist/errors.d.mts +29 -0
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +46 -2
- package/dist/errors.mjs.map +1 -0
- package/dist/headers.d.mts +26 -0
- package/dist/headers.d.mts.map +1 -0
- package/dist/headers.mjs +35 -0
- package/dist/headers.mjs.map +1 -0
- package/dist/index.d.mts +28 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +23 -8
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +33 -0
- package/dist/internal.d.mts.map +1 -0
- package/dist/internal.mjs +73 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/methods.d.mts +23 -0
- package/dist/methods.d.mts.map +1 -0
- package/dist/methods.mjs +53 -0
- package/dist/methods.mjs.map +1 -0
- package/dist/request.d.mts +31 -0
- package/dist/request.d.mts.map +1 -0
- package/dist/request.mjs +39 -0
- package/dist/request.mjs.map +1 -0
- package/dist/types.d.mts +73 -47
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +1 -1
- package/dist/url.d.mts +27 -0
- package/dist/url.d.mts.map +1 -0
- package/dist/url.mjs +56 -0
- package/dist/url.mjs.map +1 -0
- package/package.json +47 -48
- package/dist/errors-DQfwnwmz.mjs +0 -18
- package/dist/errors-DQfwnwmz.mjs.map +0 -1
- package/dist/utils.d.mts +0 -33
- package/dist/utils.d.mts.map +0 -1
- package/dist/utils.mjs +0 -180
- package/dist/utils.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @zap-studio/fetch
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- Request bodies are no longer auto-serialized from plain objects; use the explicit `json` option (or set `body` yourself). `body` and `json` are mutually exclusive at the type level and enforced at runtime.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Simplified the request API around web platform types.
|
|
12
|
+
- The first argument is named `input` and typed as `FetchInput` (`Parameters<typeof fetch>[0]` from `lib.dom`), exported from `@zap-studio/fetch/types`, so allowed inputs track global `fetch` when DOM typings change.
|
|
13
|
+
- Non-`Request` values (including `URL`) are normalized to a string URL before query merge.
|
|
14
|
+
- `ExtendedRequestInit` now extends native `RequestInit` directly instead of redefining request options.
|
|
15
|
+
- `searchParams` now accepts the same input shape as `new URLSearchParams(...)`.
|
|
16
|
+
- Replaced automatic object body serialization with an explicit `json` option.
|
|
17
|
+
- Use `json: value` when you want JSON stringification and `Content-Type: application/json`.
|
|
18
|
+
- Use native `body` when you want standard `fetch` behavior.
|
|
19
|
+
- `body` and `json` are mutually exclusive in TypeScript and guarded at runtime.
|
|
20
|
+
- Reworked URL handling to use the platform `URL` and `URLSearchParams` APIs while preserving relative URL output when no `baseURL` is configured.
|
|
21
|
+
- Simplified the internal module structure and removed the old `utils` module.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Fixed absolute URL handling when no `baseURL` is configured.
|
|
26
|
+
- `resolveSearchParams` keeps a trailing `#` when the input URL had an empty fragment (for example `.../path#`), matching typical `URL` serialization instead of dropping the delimiter.
|
|
27
|
+
|
|
28
|
+
### Tests
|
|
29
|
+
|
|
30
|
+
- Reworked tests to mirror the `src` module structure.
|
|
31
|
+
- Added full package coverage across statements, branches, functions, and lines.
|
|
32
|
+
|
|
33
|
+
### Documentation
|
|
34
|
+
|
|
35
|
+
- Documented the throwable error surface for `$fetch`, `createFetch`, and internal request execution with explicit `@throws` tags (for example `FetchError`, `ValidationError`, `TypeError`, `DOMException`, `SyntaxError`, and validator-thrown errors).
|
|
36
|
+
|
|
37
|
+
### Dependencies
|
|
38
|
+
|
|
39
|
+
- JSR dependency mapping now pins `@zap-studio/validation` to `0.3.2`.
|
|
40
|
+
|
|
41
|
+
## 0.4.7
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- e26293e: Updated dependencies.
|
|
46
|
+
- @zap-studio/validation@0.3.2
|
|
47
|
+
|
|
3
48
|
## 0.4.6
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
|
@@ -7,7 +52,6 @@
|
|
|
7
52
|
- 5ea3d3b: Updated dependencies.
|
|
8
53
|
- @zap-studio/validation@0.3.1
|
|
9
54
|
|
|
10
|
-
|
|
11
55
|
## 0.4.5
|
|
12
56
|
|
|
13
57
|
### Dependencies
|
package/{LICENSE.md → LICENSE}
RENAMED
package/README.md
CHANGED
|
@@ -1,57 +1,301 @@
|
|
|
1
1
|
# @zap-studio/fetch
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A small fetch wrapper with [**Standard Schema**](https://standardschema.dev/schema) response validation.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @zap-studio/fetch
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Example
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { api } from "@zap-studio/fetch";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
|
|
17
|
+
const UserSchema = z.object({
|
|
18
|
+
id: z.number(),
|
|
19
|
+
name: z.string(),
|
|
20
|
+
email: z.string().email(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const user = await api.get("https://api.example.com/users/1", UserSchema);
|
|
24
|
+
|
|
25
|
+
console.log(user.name);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Before
|
|
6
29
|
|
|
7
|
-
|
|
30
|
+
Without response validation, fetch code often needs unchecked assertions:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
type User = {
|
|
34
|
+
id: number;
|
|
35
|
+
name: string;
|
|
36
|
+
};
|
|
8
37
|
|
|
9
|
-
```typescript
|
|
10
38
|
const response = await fetch("/api/users/1");
|
|
11
39
|
const data = await response.json();
|
|
12
|
-
|
|
40
|
+
|
|
41
|
+
const user = data as User;
|
|
13
42
|
```
|
|
14
43
|
|
|
15
|
-
|
|
44
|
+
## After
|
|
45
|
+
|
|
46
|
+
With `@zap-studio/fetch`, the response is validated before it is returned:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { api } from "@zap-studio/fetch";
|
|
16
50
|
|
|
17
|
-
```typescript
|
|
18
51
|
const user = await api.get("/api/users/1", UserSchema);
|
|
19
|
-
// ✨ Typed, validated, and safe!
|
|
20
52
|
```
|
|
21
53
|
|
|
22
|
-
|
|
54
|
+
The returned value is inferred from the schema.
|
|
23
55
|
|
|
24
|
-
|
|
25
|
-
- 🛡️ **Runtime validation** using Standard Schema (Zod, Valibot, ArkType, etc.)
|
|
26
|
-
- ⚡️ **Convenient API methods** (GET, POST, PUT, PATCH, DELETE)
|
|
27
|
-
- 🏭 **Factory pattern** for creating pre-configured instances with base URLs
|
|
28
|
-
- 🚨 **Custom error handling** with FetchError and ValidationError classes
|
|
29
|
-
- 📘 **Full TypeScript support** with zero configuration
|
|
56
|
+
## Raw Fetch Usage
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
Use `$fetch` without a schema when you want the normal `Response` object.
|
|
32
59
|
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
60
|
+
```ts
|
|
61
|
+
import { $fetch } from "@zap-studio/fetch";
|
|
62
|
+
|
|
63
|
+
const response = await $fetch("/api/users/1");
|
|
64
|
+
const user = await response.json();
|
|
37
65
|
```
|
|
38
66
|
|
|
39
|
-
|
|
67
|
+
Native fetch options are passed through as `RequestInit`.
|
|
40
68
|
|
|
41
|
-
```
|
|
42
|
-
|
|
69
|
+
```ts
|
|
70
|
+
const response = await $fetch("/api/users", {
|
|
71
|
+
method: "POST",
|
|
72
|
+
body: JSON.stringify({ name: "Ada" }),
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Validated Fetch Usage
|
|
80
|
+
|
|
81
|
+
Pass a Standard Schema as the second argument to validate the JSON response.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { $fetch } from "@zap-studio/fetch";
|
|
85
|
+
|
|
86
|
+
const user = await $fetch("/api/users/1", UserSchema);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The schema validates the response body, not the request body.
|
|
90
|
+
|
|
91
|
+
When validation fails, a `ValidationError` is thrown by default.
|
|
92
|
+
|
|
93
|
+
## API Method Helpers
|
|
94
|
+
|
|
95
|
+
The `api` export provides common HTTP methods.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
43
98
|
import { api } from "@zap-studio/fetch";
|
|
44
99
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
100
|
+
const user = await api.get("/api/users/1", UserSchema);
|
|
101
|
+
|
|
102
|
+
const created = await api.post("/api/users", UserSchema, {
|
|
103
|
+
json: {
|
|
104
|
+
name: "Ada",
|
|
105
|
+
email: "ada@example.com",
|
|
106
|
+
},
|
|
50
107
|
});
|
|
108
|
+
```
|
|
51
109
|
|
|
52
|
-
|
|
53
|
-
|
|
110
|
+
In this example, `UserSchema` validates the response from `/api/users`.
|
|
111
|
+
The `json` value is the outgoing request body and is not validated by `UserSchema`.
|
|
112
|
+
|
|
113
|
+
These helpers set the HTTP method for you. For raw responses without validation, use `$fetch`.
|
|
114
|
+
|
|
115
|
+
## JSON Request Bodies
|
|
116
|
+
|
|
117
|
+
Use `json` when you want the package to serialize a JSON request body.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
await api.post("/api/users", UserSchema, {
|
|
121
|
+
json: {
|
|
122
|
+
name: "Ada",
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The schema argument still validates the response. Validate request bodies separately before
|
|
128
|
+
passing them to `json` if your application needs outgoing payload validation.
|
|
129
|
+
|
|
130
|
+
This sets:
|
|
131
|
+
|
|
132
|
+
- `body` to `JSON.stringify(json)`
|
|
133
|
+
- `Content-Type` to `application/json` when no content type was already provided
|
|
134
|
+
|
|
135
|
+
Use native `body` for standard fetch behavior.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
await $fetch("/api/upload", {
|
|
139
|
+
method: "POST",
|
|
140
|
+
body: formData,
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`body` and `json` are mutually exclusive.
|
|
145
|
+
|
|
146
|
+
## Query Params
|
|
147
|
+
|
|
148
|
+
Use `searchParams` for per-request query params.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
await api.get("/api/users", UserListSchema, {
|
|
152
|
+
searchParams: {
|
|
153
|
+
page: "1",
|
|
154
|
+
limit: "20",
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`searchParams` accepts the same input shapes as `new URLSearchParams(...)`.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
await api.get("/api/users", UserListSchema, {
|
|
163
|
+
searchParams: new URLSearchParams({ q: "ada" }),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await api.get("/api/users", UserListSchema, {
|
|
167
|
+
searchParams: "q=ada&page=1",
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await api.get("/api/users", UserListSchema, {
|
|
171
|
+
searchParams: [["q", "ada"]],
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
When defaults, URL query params, and request params overlap, later values win:
|
|
176
|
+
|
|
177
|
+
1. `createFetch({ searchParams })`
|
|
178
|
+
2. query params already present in the URL
|
|
179
|
+
3. per-request `searchParams`
|
|
180
|
+
|
|
181
|
+
## Creating a Client
|
|
182
|
+
|
|
183
|
+
Use `createFetch` to configure shared defaults.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { createFetch } from "@zap-studio/fetch";
|
|
187
|
+
|
|
188
|
+
const { $fetch, api } = createFetch({
|
|
189
|
+
baseURL: "https://api.example.com",
|
|
190
|
+
headers: {
|
|
191
|
+
Authorization: `Bearer ${token}`,
|
|
192
|
+
},
|
|
193
|
+
searchParams: {
|
|
194
|
+
locale: "en",
|
|
195
|
+
},
|
|
196
|
+
});
|
|
54
197
|
|
|
55
|
-
|
|
56
|
-
|
|
198
|
+
const user = await api.get("/users/1", UserSchema);
|
|
199
|
+
const response = await $fetch("/health");
|
|
57
200
|
```
|
|
201
|
+
|
|
202
|
+
Supported defaults:
|
|
203
|
+
|
|
204
|
+
| Option | Description |
|
|
205
|
+
| ------------------------ | ----------------------------------------------- |
|
|
206
|
+
| `baseURL` | Base URL for relative request URLs |
|
|
207
|
+
| `headers` | Headers applied to every request |
|
|
208
|
+
| `searchParams` | Query params applied to every request |
|
|
209
|
+
| `throwOnFetchError` | Throw `FetchError` for non-ok responses |
|
|
210
|
+
| `throwOnValidationError` | Throw `ValidationError` for validation failures |
|
|
211
|
+
|
|
212
|
+
## Non-throwing Validation
|
|
213
|
+
|
|
214
|
+
Set `throwOnValidationError: false` to receive the raw Standard Schema result.
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
const result = await api.get("/api/users/1", UserSchema, {
|
|
218
|
+
throwOnValidationError: false,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
if (result.issues) {
|
|
222
|
+
console.error("Validation failed:", result.issues);
|
|
223
|
+
} else {
|
|
224
|
+
console.log("Validation passed:", result.value);
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## HTTP Errors
|
|
229
|
+
|
|
230
|
+
By default, non-ok responses throw a `FetchError`.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { FetchError } from "@zap-studio/fetch/errors";
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
await api.get("/api/users/404", UserSchema);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
if (error instanceof FetchError) {
|
|
239
|
+
console.error(error.status);
|
|
240
|
+
console.error(error.response);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Disable this behavior when you want to handle the raw response yourself.
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const response = await $fetch("/api/users/404", {
|
|
249
|
+
throwOnFetchError: false,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
console.log(response.status);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Request Objects
|
|
256
|
+
|
|
257
|
+
The first argument (`input`) uses the same type as global `fetch`.
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
const request = new Request("https://api.example.com/users/1", {
|
|
261
|
+
headers: {
|
|
262
|
+
Authorization: `Bearer ${token}`,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const user = await $fetch(request, UserSchema);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Per-request options are merged on top of the `Request`.
|
|
270
|
+
|
|
271
|
+
## Standard Schema
|
|
272
|
+
|
|
273
|
+
`@zap-studio/fetch` validates responses through `@zap-studio/validation`, so it works with any validation library that implements Standard Schema.
|
|
274
|
+
|
|
275
|
+
Examples include:
|
|
276
|
+
|
|
277
|
+
- [Zod](https://zod.dev/)
|
|
278
|
+
- [Valibot](https://valibot.dev/)
|
|
279
|
+
- [ArkType](https://arktype.io/)
|
|
280
|
+
|
|
281
|
+
You can also import Standard Schema types from `@zap-studio/validation` when needed.
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import type { StandardSchemaV1 } from "@zap-studio/validation";
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Choosing the Right API
|
|
288
|
+
|
|
289
|
+
| API | Use when |
|
|
290
|
+
| ------------- | ------------------------------------------------- |
|
|
291
|
+
| `$fetch` | You want raw fetch behavior or a custom method |
|
|
292
|
+
| `api.get` | You want a validated GET request |
|
|
293
|
+
| `api.post` | You want a validated POST request |
|
|
294
|
+
| `api.put` | You want a validated PUT request |
|
|
295
|
+
| `api.patch` | You want a validated PATCH request |
|
|
296
|
+
| `api.delete` | You want a validated DELETE request |
|
|
297
|
+
| `createFetch` | You want shared defaults like base URL or headers |
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
MIT
|
package/dist/constants.d.mts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { FetchDefaults } from "./types.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/constants.d.ts
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* Default options for the global $fetch
|
|
6
|
+
*
|
|
7
|
+
* These defaults are used by the top-level `$fetch` export.
|
|
8
|
+
* Use `createFetch(...)` when you need per-client defaults.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { GLOBAL_DEFAULTS } from "@zap-studio/fetch/constants";
|
|
12
|
+
*
|
|
13
|
+
* console.log(GLOBAL_DEFAULTS.throwOnFetchError); // true
|
|
7
14
|
*/
|
|
8
15
|
declare const GLOBAL_DEFAULTS: FetchDefaults;
|
|
9
16
|
//#endregion
|
package/dist/constants.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.mts","names":[
|
|
1
|
+
{"version":3,"file":"constants.d.mts","names":[],"sources":["../src/constants.ts"],"mappings":";;;;;;;;;;;;;;cAmBa,eAAA,EAAiB,aAAA"}
|
package/dist/constants.mjs
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
//#region src/constants.ts
|
|
2
2
|
/**
|
|
3
3
|
* Default options for the global $fetch
|
|
4
|
+
*
|
|
5
|
+
* These defaults are used by the top-level `$fetch` export.
|
|
6
|
+
* Use `createFetch(...)` when you need per-client defaults.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import { GLOBAL_DEFAULTS } from "@zap-studio/fetch/constants";
|
|
10
|
+
*
|
|
11
|
+
* console.log(GLOBAL_DEFAULTS.throwOnFetchError); // true
|
|
4
12
|
*/
|
|
5
13
|
const GLOBAL_DEFAULTS = {
|
|
6
14
|
baseURL: "",
|
|
7
|
-
headers: void 0,
|
|
8
15
|
throwOnFetchError: true,
|
|
9
16
|
throwOnValidationError: true
|
|
10
17
|
};
|
|
11
|
-
|
|
12
18
|
//#endregion
|
|
13
19
|
export { GLOBAL_DEFAULTS };
|
|
20
|
+
|
|
14
21
|
//# sourceMappingURL=constants.mjs.map
|
package/dist/constants.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","names":[
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Shared defaults and constants for fetch behavior.\n *\n * @module\n */\n\nimport type { FetchDefaults } from \"./types.js\";\n\n/**\n * Default options for the global $fetch\n *\n * These defaults are used by the top-level `$fetch` export.\n * Use `createFetch(...)` when you need per-client defaults.\n *\n * @example\n * import { GLOBAL_DEFAULTS } from \"@zap-studio/fetch/constants\";\n *\n * console.log(GLOBAL_DEFAULTS.throwOnFetchError); // true\n */\nexport const GLOBAL_DEFAULTS: FetchDefaults = {\n baseURL: \"\",\n throwOnFetchError: true,\n throwOnValidationError: true,\n};\n"],"mappings":";;;;;;;;;;;;AAmBA,MAAa,kBAAiC;CAC5C,SAAS;CACT,mBAAmB;CACnB,wBAAwB;CACzB"}
|
package/dist/errors.d.mts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
//#region src/errors.d.ts
|
|
2
2
|
/**
|
|
3
|
+
* Custom error types used by the fetch package.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
3
8
|
* Error thrown for HTTP errors (non-2xx responses)
|
|
9
|
+
*
|
|
10
|
+
* Includes the failing `Response` object and status code for
|
|
11
|
+
* downstream error handling and response inspection.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { FetchError } from "@zap-studio/fetch/errors";
|
|
15
|
+
*
|
|
16
|
+
* try {
|
|
17
|
+
* await $fetch("/users/404");
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* if (error instanceof FetchError) {
|
|
20
|
+
* console.error(error.status);
|
|
21
|
+
* console.error(await error.response.text());
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
4
24
|
*/
|
|
5
25
|
declare class FetchError extends Error {
|
|
26
|
+
/**
|
|
27
|
+
* HTTP status code from the failing response.
|
|
28
|
+
*/
|
|
6
29
|
status: Response["status"];
|
|
30
|
+
/**
|
|
31
|
+
* Full response object for additional inspection.
|
|
32
|
+
*/
|
|
7
33
|
response: Response;
|
|
34
|
+
/**
|
|
35
|
+
* Creates a FetchError from a non-ok response.
|
|
36
|
+
*/
|
|
8
37
|
constructor(message: string, response: Response);
|
|
9
38
|
}
|
|
10
39
|
//#endregion
|
package/dist/errors.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;AAwBA;;;;;;;;;;;;;;;;;;;;;;cAAa,UAAA,SAAmB,KAAA;;;;EAI9B,MAAA,EAAQ,QAAA;;;;EAIR,QAAA,EAAU,QAAA;;;;EAKV,WAAA,CAAY,OAAA,UAAiB,QAAA,EAAU,QAAA;AAAA"}
|
package/dist/errors.mjs
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Custom error types used by the fetch package.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown for HTTP errors (non-2xx responses)
|
|
9
|
+
*
|
|
10
|
+
* Includes the failing `Response` object and status code for
|
|
11
|
+
* downstream error handling and response inspection.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { FetchError } from "@zap-studio/fetch/errors";
|
|
15
|
+
*
|
|
16
|
+
* try {
|
|
17
|
+
* await $fetch("/users/404");
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* if (error instanceof FetchError) {
|
|
20
|
+
* console.error(error.status);
|
|
21
|
+
* console.error(await error.response.text());
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
var FetchError = class extends Error {
|
|
26
|
+
/**
|
|
27
|
+
* HTTP status code from the failing response.
|
|
28
|
+
*/
|
|
29
|
+
status;
|
|
30
|
+
/**
|
|
31
|
+
* Full response object for additional inspection.
|
|
32
|
+
*/
|
|
33
|
+
response;
|
|
34
|
+
/**
|
|
35
|
+
* Creates a FetchError from a non-ok response.
|
|
36
|
+
*/
|
|
37
|
+
constructor(message, response) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "FetchError";
|
|
40
|
+
this.status = response.status;
|
|
41
|
+
this.response = response;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { FetchError };
|
|
2
46
|
|
|
3
|
-
|
|
47
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Custom error types used by the fetch package.\n *\n * @module\n */\n\n/**\n * Error thrown for HTTP errors (non-2xx responses)\n *\n * Includes the failing `Response` object and status code for\n * downstream error handling and response inspection.\n *\n * @example\n * import { FetchError } from \"@zap-studio/fetch/errors\";\n *\n * try {\n * await $fetch(\"/users/404\");\n * } catch (error) {\n * if (error instanceof FetchError) {\n * console.error(error.status);\n * console.error(await error.response.text());\n * }\n * }\n */\nexport class FetchError extends Error {\n /**\n * HTTP status code from the failing response.\n */\n status: Response[\"status\"];\n /**\n * Full response object for additional inspection.\n */\n response: Response;\n\n /**\n * Creates a FetchError from a non-ok response.\n */\n constructor(message: string, response: Response) {\n super(message);\n this.name = \"FetchError\";\n this.status = response.status;\n this.response = response;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,IAAa,aAAb,cAAgC,MAAM;;;;CAIpC;;;;CAIA;;;;CAKA,YAAY,SAAiB,UAAoB;AAC/C,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,SAAS,SAAS;AACvB,OAAK,WAAW"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/headers.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Header utility helpers for request normalization and merging.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Merges two HeadersInit objects, with the second one taking precedence.
|
|
9
|
+
*
|
|
10
|
+
* @param base - Base/default headers.
|
|
11
|
+
* @param override - Request-level override headers.
|
|
12
|
+
* @returns A merged `Headers` object, or `undefined` when both inputs are empty.
|
|
13
|
+
* @throws {TypeError} When either header input contains invalid header names or values.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const headers = mergeHeaders(
|
|
17
|
+
* { Authorization: "Bearer token" },
|
|
18
|
+
* { "X-Trace-Id": "abc" },
|
|
19
|
+
* );
|
|
20
|
+
*
|
|
21
|
+
* console.log(headers?.get("Authorization")); // Bearer token
|
|
22
|
+
*/
|
|
23
|
+
declare function mergeHeaders(base?: HeadersInit, override?: HeadersInit): Headers | undefined;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { mergeHeaders };
|
|
26
|
+
//# sourceMappingURL=headers.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.d.mts","names":[],"sources":["../src/headers.ts"],"mappings":";;AAsBA;;;;;;;;;;;;;;;;;;;;iBAAgB,YAAA,CAAa,IAAA,GAAO,WAAA,EAAa,QAAA,GAAW,WAAA,GAAc,OAAA"}
|
package/dist/headers.mjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/headers.ts
|
|
2
|
+
/**
|
|
3
|
+
* Header utility helpers for request normalization and merging.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Merges two HeadersInit objects, with the second one taking precedence.
|
|
9
|
+
*
|
|
10
|
+
* @param base - Base/default headers.
|
|
11
|
+
* @param override - Request-level override headers.
|
|
12
|
+
* @returns A merged `Headers` object, or `undefined` when both inputs are empty.
|
|
13
|
+
* @throws {TypeError} When either header input contains invalid header names or values.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const headers = mergeHeaders(
|
|
17
|
+
* { Authorization: "Bearer token" },
|
|
18
|
+
* { "X-Trace-Id": "abc" },
|
|
19
|
+
* );
|
|
20
|
+
*
|
|
21
|
+
* console.log(headers?.get("Authorization")); // Bearer token
|
|
22
|
+
*/
|
|
23
|
+
function mergeHeaders(base, override) {
|
|
24
|
+
if (!(base || override)) return;
|
|
25
|
+
const merged = new Headers(base);
|
|
26
|
+
if (override) {
|
|
27
|
+
const overrideHeaders = new Headers(override);
|
|
28
|
+
for (const [key, value] of overrideHeaders.entries()) merged.set(key, value);
|
|
29
|
+
}
|
|
30
|
+
return merged;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { mergeHeaders };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=headers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.mjs","names":[],"sources":["../src/headers.ts"],"sourcesContent":["/**\n * Header utility helpers for request normalization and merging.\n *\n * @module\n */\n\n/**\n * Merges two HeadersInit objects, with the second one taking precedence.\n *\n * @param base - Base/default headers.\n * @param override - Request-level override headers.\n * @returns A merged `Headers` object, or `undefined` when both inputs are empty.\n * @throws {TypeError} When either header input contains invalid header names or values.\n *\n * @example\n * const headers = mergeHeaders(\n * { Authorization: \"Bearer token\" },\n * { \"X-Trace-Id\": \"abc\" },\n * );\n *\n * console.log(headers?.get(\"Authorization\")); // Bearer token\n */\nexport function mergeHeaders(base?: HeadersInit, override?: HeadersInit): Headers | undefined {\n if (!(base || override)) {\n return;\n }\n\n const merged = new Headers(base);\n if (override) {\n const overrideHeaders = new Headers(override);\n for (const [key, value] of overrideHeaders.entries()) {\n merged.set(key, value);\n }\n }\n return merged;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aAAa,MAAoB,UAA6C;AAC5F,KAAI,EAAE,QAAQ,UACZ;CAGF,MAAM,SAAS,IAAI,QAAQ,KAAK;AAChC,KAAI,UAAU;EACZ,MAAM,kBAAkB,IAAI,QAAQ,SAAS;AAC7C,OAAK,MAAM,CAAC,KAAK,UAAU,gBAAgB,SAAS,CAClD,QAAO,IAAI,KAAK,MAAM;;AAG1B,QAAO"}
|