@hkdigital/lib-core 0.4.55 → 0.4.57
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/dist/network/README.md +82 -1
- package/dist/network/http/json-request.d.ts +118 -0
- package/dist/network/http/json-request.js +321 -1
- package/dist/network/http/typedef.d.ts +146 -0
- package/dist/network/http/typedef.js +56 -0
- package/dist/services/README.md +57 -6
- package/dist/util/checksum/README.md +267 -0
- package/dist/util/checksum/blockCrc32.d.ts +44 -0
- package/dist/util/checksum/blockCrc32.js +174 -0
- package/dist/util/checksum/bufferCrc32.d.ts +11 -0
- package/dist/util/checksum/bufferCrc32.js +69 -0
- package/dist/util/checksum/crcTables.d.ts +31 -0
- package/dist/util/checksum/crcTables.js +79 -0
- package/dist/util/checksum/stringCrc32.d.ts +12 -0
- package/dist/util/checksum/stringCrc32.js +33 -0
- package/dist/util/checksum/typedef.d.ts +10 -0
- package/dist/util/checksum/typedef.js +11 -0
- package/dist/util/checksum.d.ts +4 -0
- package/dist/util/checksum.js +23 -0
- package/package.json +1 -1
package/dist/network/README.md
CHANGED
|
@@ -27,6 +27,85 @@ const result = await jsonRequest('https://api.example.com/users', {
|
|
|
27
27
|
});
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
### HTTP Methods
|
|
31
|
+
|
|
32
|
+
Convenient methods for common HTTP operations:
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
import {
|
|
36
|
+
httpGet,
|
|
37
|
+
httpPost,
|
|
38
|
+
httpPut,
|
|
39
|
+
httpPatch,
|
|
40
|
+
httpDelete
|
|
41
|
+
} from '$lib/network/http.js';
|
|
42
|
+
|
|
43
|
+
// GET request
|
|
44
|
+
const response = await httpGet({ url: '/api/users' });
|
|
45
|
+
const data = await response.text();
|
|
46
|
+
|
|
47
|
+
// POST request with form data
|
|
48
|
+
const formResponse = await httpPost({
|
|
49
|
+
url: '/api/users',
|
|
50
|
+
body: new FormData(form)
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// PUT request with custom headers
|
|
54
|
+
const putResponse = await httpPut({
|
|
55
|
+
url: '/api/users/123',
|
|
56
|
+
body: 'raw data',
|
|
57
|
+
headers: { 'Content-Type': 'text/plain' }
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// PATCH request
|
|
61
|
+
const patchResponse = await httpPatch({
|
|
62
|
+
url: '/api/users/123',
|
|
63
|
+
body: JSON.stringify({ status: 'active' }),
|
|
64
|
+
headers: { 'Content-Type': 'application/json' }
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// DELETE request
|
|
68
|
+
const deleteResponse = await httpDelete({ url: '/api/users/123' });
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### JSON HTTP Methods
|
|
72
|
+
|
|
73
|
+
Convenient methods for common JSON API operations:
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
import {
|
|
77
|
+
jsonGet,
|
|
78
|
+
jsonPost,
|
|
79
|
+
jsonPut,
|
|
80
|
+
jsonPatch,
|
|
81
|
+
jsonDelete
|
|
82
|
+
} from '$lib/network/http.js';
|
|
83
|
+
|
|
84
|
+
// GET request for JSON data
|
|
85
|
+
const users = await jsonGet({ url: '/api/users' });
|
|
86
|
+
|
|
87
|
+
// POST request with JSON body
|
|
88
|
+
const newUser = await jsonPost({
|
|
89
|
+
url: '/api/users',
|
|
90
|
+
body: JSON.stringify({ name: 'Jane', email: 'jane@example.com' })
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// PUT request to update resource
|
|
94
|
+
const updatedUser = await jsonPut({
|
|
95
|
+
url: '/api/users/123',
|
|
96
|
+
body: JSON.stringify({ name: 'Jane Smith' })
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// PATCH request for partial updates
|
|
100
|
+
const patchedUser = await jsonPatch({
|
|
101
|
+
url: '/api/users/123',
|
|
102
|
+
body: JSON.stringify({ email: 'newemail@example.com' })
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// DELETE request
|
|
106
|
+
const result = await jsonDelete({ url: '/api/users/123' });
|
|
107
|
+
```
|
|
108
|
+
|
|
30
109
|
### URL Utilities
|
|
31
110
|
|
|
32
111
|
```javascript
|
|
@@ -128,7 +207,9 @@ class CustomLoader extends NetworkLoader {
|
|
|
128
207
|
|
|
129
208
|
### HTTP (`$lib/network/http.js`)
|
|
130
209
|
- `httpRequest()` - Make HTTP requests with configuration
|
|
131
|
-
- `
|
|
210
|
+
- `httpGet()`, `httpPost()`, `httpPut()`, `httpPatch()`, `httpDelete()` - Convenient HTTP methods
|
|
211
|
+
- `jsonRequest()` - Make JSON API requests
|
|
212
|
+
- `jsonGet()`, `jsonPost()`, `jsonPut()`, `jsonPatch()`, `jsonDelete()` - Convenient JSON HTTP methods
|
|
132
213
|
- `toURL()` - Convert strings to URL objects with params
|
|
133
214
|
- `setRequestHeaders()` - Set and merge request headers
|
|
134
215
|
- `waitForAndCheckResponse()` - Handle responses with error checking
|
|
@@ -82,3 +82,121 @@ export function jsonGet(options: import("./typedef").JsonGetOptions): Promise<an
|
|
|
82
82
|
* });
|
|
83
83
|
*/
|
|
84
84
|
export function jsonPost(options: import("./typedef").JsonPostOptions): Promise<any>;
|
|
85
|
+
/**
|
|
86
|
+
* Make a PUT request to fetch JSON encoded data
|
|
87
|
+
*
|
|
88
|
+
* This function performs a PUT request with JSON data and expects a JSON
|
|
89
|
+
* response from the server. It handles common error cases and parses the JSON response.
|
|
90
|
+
*
|
|
91
|
+
* @param {import('./typedef').JsonPutOptions} options
|
|
92
|
+
* Request configuration options
|
|
93
|
+
*
|
|
94
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* // Basic JSON PUT request
|
|
98
|
+
* try {
|
|
99
|
+
* const updatedUser = {
|
|
100
|
+
* name: "Jane Smith",
|
|
101
|
+
* email: "jane@example.com"
|
|
102
|
+
* };
|
|
103
|
+
*
|
|
104
|
+
* const data = await jsonPut({
|
|
105
|
+
* url: 'https://api.example.com/users/123',
|
|
106
|
+
* body: JSON.stringify(updatedUser)
|
|
107
|
+
* });
|
|
108
|
+
*
|
|
109
|
+
* console.log('Updated user:', data);
|
|
110
|
+
* } catch (error) {
|
|
111
|
+
* console.error('Failed to update user:', error.message);
|
|
112
|
+
* }
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* // JSON PUT with authentication and timeout
|
|
116
|
+
* const data = await jsonPut({
|
|
117
|
+
* url: 'https://api.example.com/protected/resource/456',
|
|
118
|
+
* body: JSON.stringify({ action: 'replace' }),
|
|
119
|
+
* headers: {
|
|
120
|
+
* 'authorization': 'Bearer ' + token
|
|
121
|
+
* },
|
|
122
|
+
* withCredentials: true,
|
|
123
|
+
* timeoutMs: 5000
|
|
124
|
+
* });
|
|
125
|
+
*/
|
|
126
|
+
export function jsonPut(options: import("./typedef").JsonPutOptions): Promise<any>;
|
|
127
|
+
/**
|
|
128
|
+
* Make a PATCH request to fetch JSON encoded data
|
|
129
|
+
*
|
|
130
|
+
* This function performs a PATCH request with JSON data and expects a JSON
|
|
131
|
+
* response from the server. It handles common error cases and parses the JSON response.
|
|
132
|
+
*
|
|
133
|
+
* @param {import('./typedef').JsonPatchOptions} options
|
|
134
|
+
* Request configuration options
|
|
135
|
+
*
|
|
136
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* // Basic JSON PATCH request
|
|
140
|
+
* try {
|
|
141
|
+
* const partialUpdate = {
|
|
142
|
+
* email: "newemail@example.com"
|
|
143
|
+
* };
|
|
144
|
+
*
|
|
145
|
+
* const data = await jsonPatch({
|
|
146
|
+
* url: 'https://api.example.com/users/123',
|
|
147
|
+
* body: JSON.stringify(partialUpdate)
|
|
148
|
+
* });
|
|
149
|
+
*
|
|
150
|
+
* console.log('Patched user:', data);
|
|
151
|
+
* } catch (error) {
|
|
152
|
+
* console.error('Failed to patch user:', error.message);
|
|
153
|
+
* }
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* // JSON PATCH with authentication and timeout
|
|
157
|
+
* const data = await jsonPatch({
|
|
158
|
+
* url: 'https://api.example.com/protected/resource/456',
|
|
159
|
+
* body: JSON.stringify({ action: 'partial_update' }),
|
|
160
|
+
* headers: {
|
|
161
|
+
* 'authorization': 'Bearer ' + token
|
|
162
|
+
* },
|
|
163
|
+
* withCredentials: true,
|
|
164
|
+
* timeoutMs: 5000
|
|
165
|
+
* });
|
|
166
|
+
*/
|
|
167
|
+
export function jsonPatch(options: import("./typedef").JsonPatchOptions): Promise<any>;
|
|
168
|
+
/**
|
|
169
|
+
* Make a DELETE request to fetch JSON encoded data
|
|
170
|
+
*
|
|
171
|
+
* This function performs a DELETE request and expects a JSON response from the server.
|
|
172
|
+
* It handles common error cases and parses the JSON response.
|
|
173
|
+
*
|
|
174
|
+
* @param {import('./typedef').JsonDeleteOptions} options
|
|
175
|
+
* Request configuration options
|
|
176
|
+
*
|
|
177
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* // Basic JSON DELETE request
|
|
181
|
+
* try {
|
|
182
|
+
* const data = await jsonDelete({
|
|
183
|
+
* url: 'https://api.example.com/users/123'
|
|
184
|
+
* });
|
|
185
|
+
* console.log('User deleted:', data);
|
|
186
|
+
* } catch (error) {
|
|
187
|
+
* console.error('Failed to delete user:', error.message);
|
|
188
|
+
* }
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* // JSON DELETE request with parameters and authentication
|
|
192
|
+
* const data = await jsonDelete({
|
|
193
|
+
* url: 'https://api.example.com/posts/456',
|
|
194
|
+
* urlSearchParams: new URLSearchParams({ force: 'true' }),
|
|
195
|
+
* headers: {
|
|
196
|
+
* 'authorization': 'Bearer ' + token
|
|
197
|
+
* },
|
|
198
|
+
* withCredentials: true,
|
|
199
|
+
* timeoutMs: 3000
|
|
200
|
+
* });
|
|
201
|
+
*/
|
|
202
|
+
export function jsonDelete(options: import("./typedef").JsonDeleteOptions): Promise<any>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { METHOD_GET, METHOD_POST } from '../../constants/http/methods.js';
|
|
1
|
+
import { METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_PATCH, METHOD_DELETE } from '../../constants/http/methods.js';
|
|
2
2
|
|
|
3
3
|
import { APPLICATION_JSON } from '../../constants/mime/application.js';
|
|
4
4
|
import { CONTENT_TYPE } from '../../constants/http/headers.js';
|
|
@@ -223,3 +223,323 @@ export async function jsonPost(options) {
|
|
|
223
223
|
|
|
224
224
|
return parsedResponse;
|
|
225
225
|
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Make a PUT request to fetch JSON encoded data
|
|
229
|
+
*
|
|
230
|
+
* This function performs a PUT request with JSON data and expects a JSON
|
|
231
|
+
* response from the server. It handles common error cases and parses the JSON response.
|
|
232
|
+
*
|
|
233
|
+
* @param {import('./typedef').JsonPutOptions} options
|
|
234
|
+
* Request configuration options
|
|
235
|
+
*
|
|
236
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* // Basic JSON PUT request
|
|
240
|
+
* try {
|
|
241
|
+
* const updatedUser = {
|
|
242
|
+
* name: "Jane Smith",
|
|
243
|
+
* email: "jane@example.com"
|
|
244
|
+
* };
|
|
245
|
+
*
|
|
246
|
+
* const data = await jsonPut({
|
|
247
|
+
* url: 'https://api.example.com/users/123',
|
|
248
|
+
* body: JSON.stringify(updatedUser)
|
|
249
|
+
* });
|
|
250
|
+
*
|
|
251
|
+
* console.log('Updated user:', data);
|
|
252
|
+
* } catch (error) {
|
|
253
|
+
* console.error('Failed to update user:', error.message);
|
|
254
|
+
* }
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* // JSON PUT with authentication and timeout
|
|
258
|
+
* const data = await jsonPut({
|
|
259
|
+
* url: 'https://api.example.com/protected/resource/456',
|
|
260
|
+
* body: JSON.stringify({ action: 'replace' }),
|
|
261
|
+
* headers: {
|
|
262
|
+
* 'authorization': 'Bearer ' + token
|
|
263
|
+
* },
|
|
264
|
+
* withCredentials: true,
|
|
265
|
+
* timeoutMs: 5000
|
|
266
|
+
* });
|
|
267
|
+
*/
|
|
268
|
+
export async function jsonPut(options) {
|
|
269
|
+
// Extract specific parameters needed for this function
|
|
270
|
+
const {
|
|
271
|
+
url: rawUrl,
|
|
272
|
+
body,
|
|
273
|
+
urlSearchParams,
|
|
274
|
+
headers,
|
|
275
|
+
withCredentials,
|
|
276
|
+
...otherOptions
|
|
277
|
+
} = options;
|
|
278
|
+
|
|
279
|
+
const url = toURL(rawUrl);
|
|
280
|
+
|
|
281
|
+
// Apply JSON-specific defaults and validation
|
|
282
|
+
expect.defined(body);
|
|
283
|
+
|
|
284
|
+
/** @type {Record<string, string>} */
|
|
285
|
+
const jsonHeaders = headers || {};
|
|
286
|
+
jsonHeaders[ACCEPT] = APPLICATION_JSON;
|
|
287
|
+
jsonHeaders[CONTENT_TYPE] = APPLICATION_JSON;
|
|
288
|
+
|
|
289
|
+
// Check if body is a string when using application/json
|
|
290
|
+
if (
|
|
291
|
+
jsonHeaders[CONTENT_TYPE] === APPLICATION_JSON &&
|
|
292
|
+
typeof body !== 'string'
|
|
293
|
+
) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`Trying to send request with [content-type:${APPLICATION_JSON}], ` +
|
|
296
|
+
'but body is not a (JSON encoded) string.'
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Create request with all options
|
|
301
|
+
const responsePromise = httpRequest({
|
|
302
|
+
method: METHOD_PUT,
|
|
303
|
+
url,
|
|
304
|
+
body,
|
|
305
|
+
urlSearchParams,
|
|
306
|
+
headers: jsonHeaders,
|
|
307
|
+
withCredentials,
|
|
308
|
+
...otherOptions // Pass through any other options
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const response = await waitForAndCheckResponse(responsePromise, url);
|
|
312
|
+
|
|
313
|
+
let parsedResponse;
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
//
|
|
317
|
+
// @note when security on the client side fails, an `opaque` response
|
|
318
|
+
// is returned by the browser (empty body) -> parsing fails
|
|
319
|
+
// (use CORS to fix this)
|
|
320
|
+
//
|
|
321
|
+
parsedResponse = await response.json();
|
|
322
|
+
} catch (e) {
|
|
323
|
+
throw new ResponseError(
|
|
324
|
+
`Failed to JSON decode server response from [${decodeURI(url.href)}]`,
|
|
325
|
+
{
|
|
326
|
+
cause: e
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (parsedResponse.error) {
|
|
332
|
+
//
|
|
333
|
+
// @note this is API specific, but it's quite logical
|
|
334
|
+
//
|
|
335
|
+
throw new ResponseError(
|
|
336
|
+
`Server returned response error message [${parsedResponse.error}]`
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return parsedResponse;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Make a PATCH request to fetch JSON encoded data
|
|
345
|
+
*
|
|
346
|
+
* This function performs a PATCH request with JSON data and expects a JSON
|
|
347
|
+
* response from the server. It handles common error cases and parses the JSON response.
|
|
348
|
+
*
|
|
349
|
+
* @param {import('./typedef').JsonPatchOptions} options
|
|
350
|
+
* Request configuration options
|
|
351
|
+
*
|
|
352
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* // Basic JSON PATCH request
|
|
356
|
+
* try {
|
|
357
|
+
* const partialUpdate = {
|
|
358
|
+
* email: "newemail@example.com"
|
|
359
|
+
* };
|
|
360
|
+
*
|
|
361
|
+
* const data = await jsonPatch({
|
|
362
|
+
* url: 'https://api.example.com/users/123',
|
|
363
|
+
* body: JSON.stringify(partialUpdate)
|
|
364
|
+
* });
|
|
365
|
+
*
|
|
366
|
+
* console.log('Patched user:', data);
|
|
367
|
+
* } catch (error) {
|
|
368
|
+
* console.error('Failed to patch user:', error.message);
|
|
369
|
+
* }
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* // JSON PATCH with authentication and timeout
|
|
373
|
+
* const data = await jsonPatch({
|
|
374
|
+
* url: 'https://api.example.com/protected/resource/456',
|
|
375
|
+
* body: JSON.stringify({ action: 'partial_update' }),
|
|
376
|
+
* headers: {
|
|
377
|
+
* 'authorization': 'Bearer ' + token
|
|
378
|
+
* },
|
|
379
|
+
* withCredentials: true,
|
|
380
|
+
* timeoutMs: 5000
|
|
381
|
+
* });
|
|
382
|
+
*/
|
|
383
|
+
export async function jsonPatch(options) {
|
|
384
|
+
// Extract specific parameters needed for this function
|
|
385
|
+
const {
|
|
386
|
+
url: rawUrl,
|
|
387
|
+
body,
|
|
388
|
+
urlSearchParams,
|
|
389
|
+
headers,
|
|
390
|
+
withCredentials,
|
|
391
|
+
...otherOptions
|
|
392
|
+
} = options;
|
|
393
|
+
|
|
394
|
+
const url = toURL(rawUrl);
|
|
395
|
+
|
|
396
|
+
// Apply JSON-specific defaults and validation
|
|
397
|
+
expect.defined(body);
|
|
398
|
+
|
|
399
|
+
/** @type {Record<string, string>} */
|
|
400
|
+
const jsonHeaders = headers || {};
|
|
401
|
+
jsonHeaders[ACCEPT] = APPLICATION_JSON;
|
|
402
|
+
jsonHeaders[CONTENT_TYPE] = APPLICATION_JSON;
|
|
403
|
+
|
|
404
|
+
// Check if body is a string when using application/json
|
|
405
|
+
if (
|
|
406
|
+
jsonHeaders[CONTENT_TYPE] === APPLICATION_JSON &&
|
|
407
|
+
typeof body !== 'string'
|
|
408
|
+
) {
|
|
409
|
+
throw new Error(
|
|
410
|
+
`Trying to send request with [content-type:${APPLICATION_JSON}], ` +
|
|
411
|
+
'but body is not a (JSON encoded) string.'
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Create request with all options
|
|
416
|
+
const responsePromise = httpRequest({
|
|
417
|
+
method: METHOD_PATCH,
|
|
418
|
+
url,
|
|
419
|
+
body,
|
|
420
|
+
urlSearchParams,
|
|
421
|
+
headers: jsonHeaders,
|
|
422
|
+
withCredentials,
|
|
423
|
+
...otherOptions // Pass through any other options
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
const response = await waitForAndCheckResponse(responsePromise, url);
|
|
427
|
+
|
|
428
|
+
let parsedResponse;
|
|
429
|
+
|
|
430
|
+
try {
|
|
431
|
+
//
|
|
432
|
+
// @note when security on the client side fails, an `opaque` response
|
|
433
|
+
// is returned by the browser (empty body) -> parsing fails
|
|
434
|
+
// (use CORS to fix this)
|
|
435
|
+
//
|
|
436
|
+
parsedResponse = await response.json();
|
|
437
|
+
} catch (e) {
|
|
438
|
+
throw new ResponseError(
|
|
439
|
+
`Failed to JSON decode server response from [${decodeURI(url.href)}]`,
|
|
440
|
+
{
|
|
441
|
+
cause: e
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (parsedResponse.error) {
|
|
447
|
+
//
|
|
448
|
+
// @note this is API specific, but it's quite logical
|
|
449
|
+
//
|
|
450
|
+
throw new ResponseError(
|
|
451
|
+
`Server returned response error message [${parsedResponse.error}]`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return parsedResponse;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Make a DELETE request to fetch JSON encoded data
|
|
460
|
+
*
|
|
461
|
+
* This function performs a DELETE request and expects a JSON response from the server.
|
|
462
|
+
* It handles common error cases and parses the JSON response.
|
|
463
|
+
*
|
|
464
|
+
* @param {import('./typedef').JsonDeleteOptions} options
|
|
465
|
+
* Request configuration options
|
|
466
|
+
*
|
|
467
|
+
* @returns {Promise<any>} Parsed JSON data
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* // Basic JSON DELETE request
|
|
471
|
+
* try {
|
|
472
|
+
* const data = await jsonDelete({
|
|
473
|
+
* url: 'https://api.example.com/users/123'
|
|
474
|
+
* });
|
|
475
|
+
* console.log('User deleted:', data);
|
|
476
|
+
* } catch (error) {
|
|
477
|
+
* console.error('Failed to delete user:', error.message);
|
|
478
|
+
* }
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* // JSON DELETE request with parameters and authentication
|
|
482
|
+
* const data = await jsonDelete({
|
|
483
|
+
* url: 'https://api.example.com/posts/456',
|
|
484
|
+
* urlSearchParams: new URLSearchParams({ force: 'true' }),
|
|
485
|
+
* headers: {
|
|
486
|
+
* 'authorization': 'Bearer ' + token
|
|
487
|
+
* },
|
|
488
|
+
* withCredentials: true,
|
|
489
|
+
* timeoutMs: 3000
|
|
490
|
+
* });
|
|
491
|
+
*/
|
|
492
|
+
export async function jsonDelete(options) {
|
|
493
|
+
// Extract specific parameters needed for this function
|
|
494
|
+
const {
|
|
495
|
+
url: rawUrl,
|
|
496
|
+
urlSearchParams,
|
|
497
|
+
headers,
|
|
498
|
+
withCredentials,
|
|
499
|
+
...otherOptions
|
|
500
|
+
} = options;
|
|
501
|
+
|
|
502
|
+
const url = toURL(rawUrl);
|
|
503
|
+
|
|
504
|
+
// Apply JSON-specific defaults
|
|
505
|
+
const jsonHeaders = headers || {};
|
|
506
|
+
jsonHeaders[ACCEPT] = APPLICATION_JSON;
|
|
507
|
+
|
|
508
|
+
// Create request with all options
|
|
509
|
+
const responsePromise = httpRequest({
|
|
510
|
+
method: METHOD_DELETE,
|
|
511
|
+
url,
|
|
512
|
+
urlSearchParams,
|
|
513
|
+
headers: jsonHeaders,
|
|
514
|
+
withCredentials,
|
|
515
|
+
...otherOptions // Pass through any other options
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
const response = await waitForAndCheckResponse(responsePromise, url);
|
|
519
|
+
|
|
520
|
+
let parsedResponse;
|
|
521
|
+
|
|
522
|
+
try {
|
|
523
|
+
//
|
|
524
|
+
// @note when security on the client side fails, an `opaque` response
|
|
525
|
+
// is returned by the browser (empty body) -> parsing fails
|
|
526
|
+
// (use CORS to fix this)
|
|
527
|
+
//
|
|
528
|
+
parsedResponse = await response.json();
|
|
529
|
+
} catch (e) {
|
|
530
|
+
throw new ResponseError(
|
|
531
|
+
`Failed to JSON decode server response from [${decodeURI(url.href)}]`,
|
|
532
|
+
{
|
|
533
|
+
cause: e
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (parsedResponse.error) {
|
|
539
|
+
throw new ResponseError(
|
|
540
|
+
`Server returned response error message [${parsedResponse.error}]`
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
return parsedResponse;
|
|
545
|
+
}
|
|
@@ -163,6 +163,152 @@ export type JsonPostOptions = {
|
|
|
163
163
|
*/
|
|
164
164
|
cacheEnabled?: boolean | undefined;
|
|
165
165
|
};
|
|
166
|
+
export type JsonPutOptions = {
|
|
167
|
+
/**
|
|
168
|
+
* URL string or URL object for the request
|
|
169
|
+
*/
|
|
170
|
+
url: string | URL;
|
|
171
|
+
/**
|
|
172
|
+
* Request body (will be sent as JSON)
|
|
173
|
+
*/
|
|
174
|
+
body: any;
|
|
175
|
+
/**
|
|
176
|
+
* Parameters to add to the URL
|
|
177
|
+
*/
|
|
178
|
+
urlSearchParams?: Object | URLSearchParams | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* HTTP headers as name-value pairs
|
|
181
|
+
*/
|
|
182
|
+
headers?: Record<string, string> | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* Whether to include credentials
|
|
185
|
+
*/
|
|
186
|
+
withCredentials?: boolean | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* Request timeout in milliseconds
|
|
189
|
+
*/
|
|
190
|
+
timeoutMs?: number | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* Handler for abort/timeout control
|
|
193
|
+
*/
|
|
194
|
+
requestHandler?: RequestHandler | undefined;
|
|
195
|
+
/**
|
|
196
|
+
* CORS mode ('cors', 'no-cors', 'same-origin')
|
|
197
|
+
*/
|
|
198
|
+
mode?: string | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* Cache mode ('default', 'no-cache', etc.)
|
|
201
|
+
*/
|
|
202
|
+
cache?: string | undefined;
|
|
203
|
+
/**
|
|
204
|
+
* Redirect mode ('follow', 'error', 'manual')
|
|
205
|
+
*/
|
|
206
|
+
redirect?: string | undefined;
|
|
207
|
+
/**
|
|
208
|
+
* Referrer policy
|
|
209
|
+
*/
|
|
210
|
+
referrerPolicy?: string | undefined;
|
|
211
|
+
/**
|
|
212
|
+
* Enable or disabled automatic caching
|
|
213
|
+
*/
|
|
214
|
+
cacheEnabled?: boolean | undefined;
|
|
215
|
+
};
|
|
216
|
+
export type JsonPatchOptions = {
|
|
217
|
+
/**
|
|
218
|
+
* URL string or URL object for the request
|
|
219
|
+
*/
|
|
220
|
+
url: string | URL;
|
|
221
|
+
/**
|
|
222
|
+
* Request body (will be sent as JSON)
|
|
223
|
+
*/
|
|
224
|
+
body: any;
|
|
225
|
+
/**
|
|
226
|
+
* Parameters to add to the URL
|
|
227
|
+
*/
|
|
228
|
+
urlSearchParams?: Object | URLSearchParams | undefined;
|
|
229
|
+
/**
|
|
230
|
+
* HTTP headers as name-value pairs
|
|
231
|
+
*/
|
|
232
|
+
headers?: Record<string, string> | undefined;
|
|
233
|
+
/**
|
|
234
|
+
* Whether to include credentials
|
|
235
|
+
*/
|
|
236
|
+
withCredentials?: boolean | undefined;
|
|
237
|
+
/**
|
|
238
|
+
* Request timeout in milliseconds
|
|
239
|
+
*/
|
|
240
|
+
timeoutMs?: number | undefined;
|
|
241
|
+
/**
|
|
242
|
+
* Handler for abort/timeout control
|
|
243
|
+
*/
|
|
244
|
+
requestHandler?: RequestHandler | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* CORS mode ('cors', 'no-cors', 'same-origin')
|
|
247
|
+
*/
|
|
248
|
+
mode?: string | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* Cache mode ('default', 'no-cache', etc.)
|
|
251
|
+
*/
|
|
252
|
+
cache?: string | undefined;
|
|
253
|
+
/**
|
|
254
|
+
* Redirect mode ('follow', 'error', 'manual')
|
|
255
|
+
*/
|
|
256
|
+
redirect?: string | undefined;
|
|
257
|
+
/**
|
|
258
|
+
* Referrer policy
|
|
259
|
+
*/
|
|
260
|
+
referrerPolicy?: string | undefined;
|
|
261
|
+
/**
|
|
262
|
+
* Enable or disabled automatic caching
|
|
263
|
+
*/
|
|
264
|
+
cacheEnabled?: boolean | undefined;
|
|
265
|
+
};
|
|
266
|
+
export type JsonDeleteOptions = {
|
|
267
|
+
/**
|
|
268
|
+
* URL string or URL object for the request
|
|
269
|
+
*/
|
|
270
|
+
url: string | URL;
|
|
271
|
+
/**
|
|
272
|
+
* Parameters to add to the URL
|
|
273
|
+
*/
|
|
274
|
+
urlSearchParams?: Object | URLSearchParams | undefined;
|
|
275
|
+
/**
|
|
276
|
+
* HTTP headers as name-value pairs
|
|
277
|
+
*/
|
|
278
|
+
headers?: Record<string, string> | undefined;
|
|
279
|
+
/**
|
|
280
|
+
* Whether to include credentials
|
|
281
|
+
*/
|
|
282
|
+
withCredentials?: boolean | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* Request timeout in milliseconds
|
|
285
|
+
*/
|
|
286
|
+
timeoutMs?: number | undefined;
|
|
287
|
+
/**
|
|
288
|
+
* Handler for abort/timeout control
|
|
289
|
+
*/
|
|
290
|
+
requestHandler?: RequestHandler | undefined;
|
|
291
|
+
/**
|
|
292
|
+
* CORS mode ('cors', 'no-cors', 'same-origin')
|
|
293
|
+
*/
|
|
294
|
+
mode?: string | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Cache mode ('default', 'no-cache', etc.')
|
|
297
|
+
*/
|
|
298
|
+
cache?: string | undefined;
|
|
299
|
+
/**
|
|
300
|
+
* Redirect mode ('follow', 'error', 'manual')
|
|
301
|
+
*/
|
|
302
|
+
redirect?: string | undefined;
|
|
303
|
+
/**
|
|
304
|
+
* Referrer policy
|
|
305
|
+
*/
|
|
306
|
+
referrerPolicy?: string | undefined;
|
|
307
|
+
/**
|
|
308
|
+
* Enable or disabled automatic caching
|
|
309
|
+
*/
|
|
310
|
+
cacheEnabled?: boolean | undefined;
|
|
311
|
+
};
|
|
166
312
|
export type StaleInfo = {
|
|
167
313
|
/**
|
|
168
314
|
* Whether the response contains stale data
|