@marianmeres/http-utils 2.2.0 → 2.3.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/AGENTS.md +14 -1
- package/API.md +54 -12
- package/README.md +31 -17
- package/dist/api.d.ts +14 -0
- package/dist/api.js +72 -117
- package/dist/mod.d.ts +1 -1
- package/dist/mod.js +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -103,6 +103,13 @@ HTTP_ERROR.BadGateway // 502
|
|
|
103
103
|
HTTP_ERROR.ServiceUnavailable // 503
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
### Helper Functions
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Marks options object for options-based API (vs legacy positional API)
|
|
110
|
+
function opts<T extends GetOptions | DataOptions>(options: T): T
|
|
111
|
+
```
|
|
112
|
+
|
|
106
113
|
### Utility Functions
|
|
107
114
|
|
|
108
115
|
```typescript
|
|
@@ -168,12 +175,18 @@ deno task publish # Publish to JSR and NPM
|
|
|
168
175
|
### Basic Usage
|
|
169
176
|
|
|
170
177
|
```typescript
|
|
178
|
+
import { createHttpApi, opts } from "@marianmeres/http-utils";
|
|
179
|
+
|
|
171
180
|
const api = createHttpApi("https://api.example.com", {
|
|
172
181
|
headers: { "Authorization": "Bearer token" }
|
|
173
182
|
});
|
|
174
183
|
|
|
184
|
+
// Legacy API (default - object is request body)
|
|
175
185
|
const data = await api.get("/users");
|
|
176
|
-
await api.post("/users", {
|
|
186
|
+
await api.post("/users", { name: "John" });
|
|
187
|
+
|
|
188
|
+
// Options API (requires opts() wrapper)
|
|
189
|
+
await api.post("/users", opts({ data: { name: "John" }, params: { token: "abc" } }));
|
|
177
190
|
```
|
|
178
191
|
|
|
179
192
|
### Error Handling
|
package/API.md
CHANGED
|
@@ -5,6 +5,7 @@ Complete API reference for `@marianmeres/http-utils`.
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
7
|
- [createHttpApi](#createhttpapi)
|
|
8
|
+
- [opts](#opts)
|
|
8
9
|
- [HttpApi Class](#httpapi-class)
|
|
9
10
|
- [Types](#types)
|
|
10
11
|
- [HTTP Errors](#http-errors)
|
|
@@ -78,6 +79,47 @@ Priority order: per-request > per-instance > global > built-in fallback.
|
|
|
78
79
|
|
|
79
80
|
---
|
|
80
81
|
|
|
82
|
+
## opts
|
|
83
|
+
|
|
84
|
+
Marks an options object for the options-based API. Without this wrapper, arguments are treated as legacy positional parameters.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
function opts<T extends GetOptions | DataOptions>(options: T): T
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Why `opts()`?
|
|
91
|
+
|
|
92
|
+
The library supports two API styles:
|
|
93
|
+
- **Legacy API**: Positional parameters (backward compatible)
|
|
94
|
+
- **Options API**: Single options object with named properties
|
|
95
|
+
|
|
96
|
+
The `opts()` wrapper explicitly indicates which style you're using, preventing ambiguity when your request data might look like an options object.
|
|
97
|
+
|
|
98
|
+
### Example
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { createHttpApi, opts } from "@marianmeres/http-utils";
|
|
102
|
+
|
|
103
|
+
const api = createHttpApi("https://api.example.com");
|
|
104
|
+
|
|
105
|
+
// Without opts() - legacy behavior: entire object is sent as request body
|
|
106
|
+
await api.post("/users", { data: { name: "John" } });
|
|
107
|
+
// Sends: { "data": { "name": "John" } }
|
|
108
|
+
|
|
109
|
+
// With opts() - options API: data is extracted and sent as body
|
|
110
|
+
await api.post("/users", opts({ data: { name: "John" } }));
|
|
111
|
+
// Sends: { "name": "John" }
|
|
112
|
+
|
|
113
|
+
// GET with options
|
|
114
|
+
const respHeaders = {};
|
|
115
|
+
await api.get("/users", opts({
|
|
116
|
+
params: { headers: { "X-Custom": "value" } },
|
|
117
|
+
respHeaders
|
|
118
|
+
}));
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
81
123
|
## HttpApi Class
|
|
82
124
|
|
|
83
125
|
HTTP API client class. Usually created via `createHttpApi()`.
|
|
@@ -88,12 +130,12 @@ HTTP API client class. Usually created via `createHttpApi()`.
|
|
|
88
130
|
|
|
89
131
|
Performs a GET request.
|
|
90
132
|
|
|
91
|
-
**
|
|
133
|
+
**Options API (with `opts()` wrapper):**
|
|
92
134
|
```ts
|
|
93
135
|
async get<T = unknown>(path: string, options?: GetOptions): Promise<T>
|
|
94
136
|
```
|
|
95
137
|
|
|
96
|
-
**Legacy API:**
|
|
138
|
+
**Legacy API (default behavior):**
|
|
97
139
|
```ts
|
|
98
140
|
async get<T = unknown>(
|
|
99
141
|
path: string,
|
|
@@ -105,17 +147,17 @@ async get<T = unknown>(
|
|
|
105
147
|
|
|
106
148
|
**Example:**
|
|
107
149
|
```ts
|
|
108
|
-
//
|
|
150
|
+
// Options API with type parameter (requires opts() wrapper)
|
|
109
151
|
interface User { id: number; name: string; }
|
|
110
|
-
const user = await api.get<User>("/users/1", {
|
|
152
|
+
const user = await api.get<User>("/users/1", opts({
|
|
111
153
|
params: { headers: { "X-Custom": "value" } },
|
|
112
154
|
respHeaders: {}
|
|
113
|
-
});
|
|
155
|
+
}));
|
|
114
156
|
|
|
115
157
|
// Without type parameter (returns unknown)
|
|
116
158
|
const data = await api.get("/users");
|
|
117
159
|
|
|
118
|
-
// Legacy API
|
|
160
|
+
// Legacy API (no opts() needed)
|
|
119
161
|
const data = await api.get("/users", { headers: { "X-Custom": "value" } });
|
|
120
162
|
```
|
|
121
163
|
|
|
@@ -123,12 +165,12 @@ const data = await api.get("/users", { headers: { "X-Custom": "value" } });
|
|
|
123
165
|
|
|
124
166
|
Performs a POST request.
|
|
125
167
|
|
|
126
|
-
**
|
|
168
|
+
**Options API (with `opts()` wrapper):**
|
|
127
169
|
```ts
|
|
128
170
|
async post<T = unknown>(path: string, options?: DataOptions): Promise<T>
|
|
129
171
|
```
|
|
130
172
|
|
|
131
|
-
**Legacy API:**
|
|
173
|
+
**Legacy API (default behavior):**
|
|
132
174
|
```ts
|
|
133
175
|
async post<T = unknown>(
|
|
134
176
|
path: string,
|
|
@@ -141,14 +183,14 @@ async post<T = unknown>(
|
|
|
141
183
|
|
|
142
184
|
**Example:**
|
|
143
185
|
```ts
|
|
144
|
-
//
|
|
186
|
+
// Options API with type parameter (requires opts() wrapper)
|
|
145
187
|
interface User { id: number; name: string; }
|
|
146
|
-
const user = await api.post<User>("/users", {
|
|
188
|
+
const user = await api.post<User>("/users", opts({
|
|
147
189
|
data: { name: "John" },
|
|
148
190
|
params: { headers: { "X-Custom": "value" } }
|
|
149
|
-
});
|
|
191
|
+
}));
|
|
150
192
|
|
|
151
|
-
// Legacy API
|
|
193
|
+
// Legacy API (no opts() needed)
|
|
152
194
|
const result = await api.post("/users", { name: "John" });
|
|
153
195
|
```
|
|
154
196
|
|
package/README.md
CHANGED
|
@@ -26,38 +26,38 @@ npm install @marianmeres/http-utils
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
|
-
import { createHttpApi, HTTP_ERROR } from "@marianmeres/http-utils";
|
|
29
|
+
import { createHttpApi, opts, HTTP_ERROR } from "@marianmeres/http-utils";
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Quick Start
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
|
-
import { createHttpApi, HTTP_ERROR, NotFound } from "@marianmeres/http-utils";
|
|
35
|
+
import { createHttpApi, opts, HTTP_ERROR, NotFound } from "@marianmeres/http-utils";
|
|
36
36
|
|
|
37
37
|
// Create an API client with base URL
|
|
38
38
|
const api = createHttpApi("https://api.example.com", {
|
|
39
39
|
headers: { "Authorization": "Bearer your-token" }
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
// GET request (
|
|
43
|
-
const users = await api.get("/users", {
|
|
42
|
+
// GET request (options API with opts() wrapper)
|
|
43
|
+
const users = await api.get("/users", opts({
|
|
44
44
|
params: { headers: { "X-Custom": "value" } }
|
|
45
|
-
});
|
|
45
|
+
}));
|
|
46
46
|
|
|
47
|
-
// POST request (
|
|
48
|
-
const newUser = await api.post("/users", {
|
|
47
|
+
// POST request (options API with opts() wrapper)
|
|
48
|
+
const newUser = await api.post("/users", opts({
|
|
49
49
|
data: { name: "John Doe" },
|
|
50
50
|
params: { headers: { "X-Custom": "value" } }
|
|
51
|
-
});
|
|
51
|
+
}));
|
|
52
52
|
|
|
53
|
-
// Legacy API
|
|
53
|
+
// Legacy API (default behavior without opts())
|
|
54
54
|
const legacyUsers = await api.get("/users", { headers: { "X-Custom": "value" } });
|
|
55
55
|
const legacyUser = await api.post("/users", { name: "John Doe" });
|
|
56
56
|
|
|
57
57
|
// With type parameters for typed responses
|
|
58
58
|
interface User { id: number; name: string; }
|
|
59
59
|
const user = await api.get<User>("/users/1");
|
|
60
|
-
const created = await api.post<User>("/users", { data: { name: "Jane" } });
|
|
60
|
+
const created = await api.post<User>("/users", opts({ data: { name: "Jane" } }));
|
|
61
61
|
|
|
62
62
|
// Error handling
|
|
63
63
|
try {
|
|
@@ -89,23 +89,37 @@ const api = createHttpApi("https://api.example.com", {
|
|
|
89
89
|
### HTTP Methods
|
|
90
90
|
|
|
91
91
|
```ts
|
|
92
|
-
// GET (
|
|
93
|
-
const data = await api.get("/users", {
|
|
92
|
+
// GET (options API with opts() wrapper)
|
|
93
|
+
const data = await api.get("/users", opts({
|
|
94
94
|
params: { headers: { "X-Custom": "value" } },
|
|
95
95
|
respHeaders: {}
|
|
96
|
-
});
|
|
96
|
+
}));
|
|
97
97
|
|
|
98
|
-
// POST/PUT/PATCH/DELETE (
|
|
99
|
-
await api.post("/users", {
|
|
98
|
+
// POST/PUT/PATCH/DELETE (options API with opts() wrapper)
|
|
99
|
+
await api.post("/users", opts({
|
|
100
100
|
data: { name: "John" },
|
|
101
101
|
params: { token: "bearer-token" }
|
|
102
|
-
});
|
|
102
|
+
}));
|
|
103
103
|
|
|
104
|
-
// Legacy API
|
|
104
|
+
// Legacy API (default behavior without opts())
|
|
105
105
|
const data = await api.get("/users", { headers: { "X-Custom": "value" } });
|
|
106
106
|
await api.post("/users", { name: "John" });
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
### The `opts()` Helper
|
|
110
|
+
|
|
111
|
+
The `opts()` function explicitly marks an options object for the options-based API. Without it, arguments are treated as legacy positional parameters.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Without opts() - legacy behavior: object is sent as request body
|
|
115
|
+
await api.post("/users", { data: { name: "John" } }); // Sends: { data: { name: "John" } }
|
|
116
|
+
|
|
117
|
+
// With opts() - options API: data is extracted and sent as body
|
|
118
|
+
await api.post("/users", opts({ data: { name: "John" } })); // Sends: { name: "John" }
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This makes the API unambiguous and prevents accidental misinterpretation of request data.
|
|
122
|
+
|
|
109
123
|
### Error Handling
|
|
110
124
|
|
|
111
125
|
```ts
|
package/dist/api.d.ts
CHANGED
|
@@ -71,6 +71,20 @@ export interface DataOptions {
|
|
|
71
71
|
/** Custom error message extractor for this request. */
|
|
72
72
|
errorExtractor?: ErrorMessageExtractor | null;
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Marks an options object for the new options API.
|
|
76
|
+
* Use this to explicitly indicate you're using the options-based API.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* // GET with options
|
|
81
|
+
* await api.get('/users', opts({ params: { token: 'abc' } }));
|
|
82
|
+
*
|
|
83
|
+
* // POST with options
|
|
84
|
+
* await api.post('/users', opts({ data: { name: 'John' }, params: { token: 'abc' } }));
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function opts<T extends GetOptions | DataOptions>(options: T): T;
|
|
74
88
|
/**
|
|
75
89
|
* HTTP API client with convenient defaults and error handling.
|
|
76
90
|
*/
|
package/dist/api.js
CHANGED
|
@@ -32,6 +32,68 @@ function deepMerge(target, source) {
|
|
|
32
32
|
function isObject(item) {
|
|
33
33
|
return item !== null && typeof item === 'object' && !Array.isArray(item);
|
|
34
34
|
}
|
|
35
|
+
/** Symbol marker for explicit options API detection. */
|
|
36
|
+
const OPTIONS_MARKER = Symbol('options');
|
|
37
|
+
/**
|
|
38
|
+
* Marks an options object for the new options API.
|
|
39
|
+
* Use this to explicitly indicate you're using the options-based API.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* // GET with options
|
|
44
|
+
* await api.get('/users', opts({ params: { token: 'abc' } }));
|
|
45
|
+
*
|
|
46
|
+
* // POST with options
|
|
47
|
+
* await api.post('/users', opts({ data: { name: 'John' }, params: { token: 'abc' } }));
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function opts(options) {
|
|
51
|
+
return Object.assign(options, { [OPTIONS_MARKER]: true });
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parses GET method arguments, detecting new options API via OPTIONS_MARKER.
|
|
55
|
+
*/
|
|
56
|
+
function parseGetOptions(paramsOrOptions, legacyRespHeaders, legacyErrorExtractor) {
|
|
57
|
+
if (paramsOrOptions && OPTIONS_MARKER in paramsOrOptions) {
|
|
58
|
+
// New options API (explicit via opts() wrapper)
|
|
59
|
+
const o = paramsOrOptions;
|
|
60
|
+
return {
|
|
61
|
+
params: o.params,
|
|
62
|
+
respHeaders: o.respHeaders ?? null,
|
|
63
|
+
errorExtractor: o.errorExtractor ?? null,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Legacy positional API
|
|
67
|
+
return {
|
|
68
|
+
params: paramsOrOptions,
|
|
69
|
+
respHeaders: legacyRespHeaders ?? null,
|
|
70
|
+
errorExtractor: legacyErrorExtractor ?? null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parses body method arguments (POST/PUT/PATCH/DELETE), detecting new options API via OPTIONS_MARKER.
|
|
75
|
+
*/
|
|
76
|
+
function parseDataOptions(dataOrOptions, legacyParams, legacyRespHeaders, legacyErrorExtractor) {
|
|
77
|
+
if (dataOrOptions &&
|
|
78
|
+
typeof dataOrOptions === 'object' &&
|
|
79
|
+
OPTIONS_MARKER in dataOrOptions) {
|
|
80
|
+
// New options API (explicit via opts() wrapper)
|
|
81
|
+
const o = dataOrOptions;
|
|
82
|
+
return {
|
|
83
|
+
data: o.data ?? null,
|
|
84
|
+
params: o.params,
|
|
85
|
+
respHeaders: o.respHeaders ?? null,
|
|
86
|
+
errorExtractor: o.errorExtractor ?? null,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// Legacy positional API
|
|
90
|
+
return {
|
|
91
|
+
data: dataOrOptions ?? null,
|
|
92
|
+
params: legacyParams,
|
|
93
|
+
respHeaders: legacyRespHeaders ?? null,
|
|
94
|
+
errorExtractor: legacyErrorExtractor ?? null,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
35
97
|
const _fetchRaw = async ({ method, path, data = null, token = null, headers = null, signal, credentials, }) => {
|
|
36
98
|
const normalizedHeaders = Object.entries(headers || {}).reduce((m, [k, v]) => ({ ...m, [k.toLowerCase()]: v }), {});
|
|
37
99
|
const opts = {
|
|
@@ -142,136 +204,29 @@ export class HttpApi {
|
|
|
142
204
|
return /^https?:/.test(path) ? path : base + path;
|
|
143
205
|
}
|
|
144
206
|
async get(path, paramsOrOptions, respHeaders, errorMessageExtractor, _dumpParams = false) {
|
|
145
|
-
|
|
146
|
-
let params;
|
|
147
|
-
let headers = null;
|
|
148
|
-
let extractor = null;
|
|
149
|
-
if (paramsOrOptions && ('respHeaders' in paramsOrOptions || 'errorExtractor' in paramsOrOptions)) {
|
|
150
|
-
// New options API
|
|
151
|
-
const opts = paramsOrOptions;
|
|
152
|
-
params = opts.params;
|
|
153
|
-
headers = opts.respHeaders ?? null;
|
|
154
|
-
extractor = opts.errorExtractor ?? null;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
// Legacy positional API
|
|
158
|
-
params = paramsOrOptions;
|
|
159
|
-
headers = respHeaders ?? null;
|
|
160
|
-
extractor = errorMessageExtractor ?? null;
|
|
161
|
-
}
|
|
207
|
+
const { params, respHeaders: headers, errorExtractor } = parseGetOptions(paramsOrOptions, respHeaders, errorMessageExtractor);
|
|
162
208
|
path = this.#buildPath(path, this.#base);
|
|
163
|
-
return _fetch(this.#merge(await this.#getDefs(), { ...params, method: 'GET', path }), headers,
|
|
209
|
+
return _fetch(this.#merge(await this.#getDefs(), { ...params, method: 'GET', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
|
|
164
210
|
}
|
|
165
211
|
async post(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
|
|
166
|
-
|
|
167
|
-
let data = null;
|
|
168
|
-
let fetchParams;
|
|
169
|
-
let headers = null;
|
|
170
|
-
let extractor = null;
|
|
171
|
-
if (dataOrOptions &&
|
|
172
|
-
typeof dataOrOptions === 'object' &&
|
|
173
|
-
!(dataOrOptions instanceof FormData) &&
|
|
174
|
-
('data' in dataOrOptions ||
|
|
175
|
-
'params' in dataOrOptions ||
|
|
176
|
-
'respHeaders' in dataOrOptions ||
|
|
177
|
-
'errorExtractor' in dataOrOptions)) {
|
|
178
|
-
// New options API
|
|
179
|
-
const opts = dataOrOptions;
|
|
180
|
-
data = opts.data ?? null;
|
|
181
|
-
fetchParams = opts.params;
|
|
182
|
-
headers = opts.respHeaders ?? null;
|
|
183
|
-
extractor = opts.errorExtractor ?? null;
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
// Legacy positional API
|
|
187
|
-
data = dataOrOptions ?? null;
|
|
188
|
-
fetchParams = params;
|
|
189
|
-
headers = respHeaders ?? null;
|
|
190
|
-
extractor = errorMessageExtractor ?? null;
|
|
191
|
-
}
|
|
212
|
+
const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
|
|
192
213
|
path = this.#buildPath(path, this.#base);
|
|
193
|
-
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'POST', path }), headers,
|
|
214
|
+
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'POST', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
|
|
194
215
|
}
|
|
195
216
|
async put(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
|
|
196
|
-
|
|
197
|
-
let fetchParams;
|
|
198
|
-
let headers = null;
|
|
199
|
-
let extractor = null;
|
|
200
|
-
if (dataOrOptions &&
|
|
201
|
-
typeof dataOrOptions === 'object' &&
|
|
202
|
-
!(dataOrOptions instanceof FormData) &&
|
|
203
|
-
('data' in dataOrOptions ||
|
|
204
|
-
'params' in dataOrOptions ||
|
|
205
|
-
'respHeaders' in dataOrOptions ||
|
|
206
|
-
'errorExtractor' in dataOrOptions)) {
|
|
207
|
-
const opts = dataOrOptions;
|
|
208
|
-
data = opts.data ?? null;
|
|
209
|
-
fetchParams = opts.params;
|
|
210
|
-
headers = opts.respHeaders ?? null;
|
|
211
|
-
extractor = opts.errorExtractor ?? null;
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
data = dataOrOptions ?? null;
|
|
215
|
-
fetchParams = params;
|
|
216
|
-
headers = respHeaders ?? null;
|
|
217
|
-
extractor = errorMessageExtractor ?? null;
|
|
218
|
-
}
|
|
217
|
+
const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
|
|
219
218
|
path = this.#buildPath(path, this.#base);
|
|
220
|
-
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PUT', path }), headers,
|
|
219
|
+
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PUT', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
|
|
221
220
|
}
|
|
222
221
|
async patch(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
|
|
223
|
-
|
|
224
|
-
let fetchParams;
|
|
225
|
-
let headers = null;
|
|
226
|
-
let extractor = null;
|
|
227
|
-
if (dataOrOptions &&
|
|
228
|
-
typeof dataOrOptions === 'object' &&
|
|
229
|
-
!(dataOrOptions instanceof FormData) &&
|
|
230
|
-
('data' in dataOrOptions ||
|
|
231
|
-
'params' in dataOrOptions ||
|
|
232
|
-
'respHeaders' in dataOrOptions ||
|
|
233
|
-
'errorExtractor' in dataOrOptions)) {
|
|
234
|
-
const opts = dataOrOptions;
|
|
235
|
-
data = opts.data ?? null;
|
|
236
|
-
fetchParams = opts.params;
|
|
237
|
-
headers = opts.respHeaders ?? null;
|
|
238
|
-
extractor = opts.errorExtractor ?? null;
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
data = dataOrOptions ?? null;
|
|
242
|
-
fetchParams = params;
|
|
243
|
-
headers = respHeaders ?? null;
|
|
244
|
-
extractor = errorMessageExtractor ?? null;
|
|
245
|
-
}
|
|
222
|
+
const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
|
|
246
223
|
path = this.#buildPath(path, this.#base);
|
|
247
|
-
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PATCH', path }), headers,
|
|
224
|
+
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PATCH', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
|
|
248
225
|
}
|
|
249
226
|
async del(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
|
|
250
|
-
|
|
251
|
-
let fetchParams;
|
|
252
|
-
let headers = null;
|
|
253
|
-
let extractor = null;
|
|
254
|
-
if (dataOrOptions &&
|
|
255
|
-
typeof dataOrOptions === 'object' &&
|
|
256
|
-
!(dataOrOptions instanceof FormData) &&
|
|
257
|
-
('data' in dataOrOptions ||
|
|
258
|
-
'params' in dataOrOptions ||
|
|
259
|
-
'respHeaders' in dataOrOptions ||
|
|
260
|
-
'errorExtractor' in dataOrOptions)) {
|
|
261
|
-
const opts = dataOrOptions;
|
|
262
|
-
data = opts.data ?? null;
|
|
263
|
-
fetchParams = opts.params;
|
|
264
|
-
headers = opts.respHeaders ?? null;
|
|
265
|
-
extractor = opts.errorExtractor ?? null;
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
data = dataOrOptions ?? null;
|
|
269
|
-
fetchParams = params;
|
|
270
|
-
headers = respHeaders ?? null;
|
|
271
|
-
extractor = errorMessageExtractor ?? null;
|
|
272
|
-
}
|
|
227
|
+
const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
|
|
273
228
|
path = this.#buildPath(path, this.#base);
|
|
274
|
-
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'DELETE', path }), headers,
|
|
229
|
+
return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'DELETE', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
|
|
275
230
|
}
|
|
276
231
|
/**
|
|
277
232
|
* Helper method to build the full URL from a path.
|
package/dist/mod.d.ts
CHANGED
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
* }
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
export { HttpApi, createHttpApi, type DataOptions, type GetOptions, type FetchParams, type ErrorMessageExtractor, type ResponseHeaders, type RequestData, } from "./api.js";
|
|
24
|
+
export { HttpApi, createHttpApi, opts, type DataOptions, type GetOptions, type FetchParams, type ErrorMessageExtractor, type ResponseHeaders, type RequestData, } from "./api.js";
|
|
25
25
|
export { HTTP_ERROR, createHttpError, getErrorMessage } from "./error.js";
|
|
26
26
|
export { HTTP_STATUS } from "./status.js";
|
package/dist/mod.js
CHANGED