@cacheable/net 1.0.2 → 2.0.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/README.md +156 -13
- package/dist/index.cjs +185 -41
- package/dist/index.d.cts +141 -30
- package/dist/index.d.ts +141 -30
- package/dist/index.js +185 -41
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -8,13 +8,17 @@ import {
|
|
|
8
8
|
fetch as undiciFetch
|
|
9
9
|
} from "undici";
|
|
10
10
|
async function fetch(url, options) {
|
|
11
|
-
if (!options.cache) {
|
|
12
|
-
throw new Error("Fetch options must include a cache instance or options.");
|
|
13
|
-
}
|
|
14
11
|
const fetchOptions = {
|
|
15
12
|
...options,
|
|
16
13
|
cache: "no-cache"
|
|
17
14
|
};
|
|
15
|
+
if (!options.cache) {
|
|
16
|
+
const response2 = await undiciFetch(url, fetchOptions);
|
|
17
|
+
if (!response2.ok) {
|
|
18
|
+
throw new Error(`Fetch failed with status ${response2.status}`);
|
|
19
|
+
}
|
|
20
|
+
return response2;
|
|
21
|
+
}
|
|
18
22
|
if (options.method === "POST" || options.method === "PATCH" || options.method === "DELETE" || options.method === "HEAD") {
|
|
19
23
|
const response2 = await undiciFetch(url, fetchOptions);
|
|
20
24
|
if (!response2.ok) {
|
|
@@ -22,10 +26,10 @@ async function fetch(url, options) {
|
|
|
22
26
|
}
|
|
23
27
|
return response2;
|
|
24
28
|
}
|
|
25
|
-
const
|
|
29
|
+
const httpCachePolicy = options.httpCachePolicy !== false;
|
|
26
30
|
const method = options.method || "GET";
|
|
27
31
|
const cacheKey = `${method}:${url}`;
|
|
28
|
-
if (!
|
|
32
|
+
if (!httpCachePolicy) {
|
|
29
33
|
const cachedData = await options.cache.getOrSet(cacheKey, async () => {
|
|
30
34
|
const response2 = await undiciFetch(url, fetchOptions);
|
|
31
35
|
if (!response2.ok) {
|
|
@@ -301,67 +305,122 @@ async function head(url, options) {
|
|
|
301
305
|
// src/index.ts
|
|
302
306
|
var CacheableNet = class extends Hookified {
|
|
303
307
|
_cache = new Cacheable();
|
|
304
|
-
|
|
308
|
+
_httpCachePolicy = true;
|
|
309
|
+
_stringify = JSON.stringify;
|
|
310
|
+
_parse = JSON.parse;
|
|
305
311
|
constructor(options) {
|
|
306
312
|
super(options);
|
|
307
313
|
if (options?.cache) {
|
|
308
314
|
this._cache = options.cache instanceof Cacheable ? options.cache : new Cacheable(options.cache);
|
|
309
315
|
}
|
|
310
|
-
if (options?.
|
|
311
|
-
this.
|
|
316
|
+
if (options?.httpCachePolicy !== void 0) {
|
|
317
|
+
this._httpCachePolicy = options.httpCachePolicy;
|
|
318
|
+
}
|
|
319
|
+
if (options?.stringify) {
|
|
320
|
+
this._stringify = options?.stringify;
|
|
312
321
|
}
|
|
322
|
+
if (options?.parse) {
|
|
323
|
+
this._parse = options?.parse;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Get the stringify function used for converting objects to strings.
|
|
328
|
+
* @returns {StringifyType} The current stringify function
|
|
329
|
+
*/
|
|
330
|
+
get stringify() {
|
|
331
|
+
return this._stringify;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Set the stringify function for converting objects to strings.
|
|
335
|
+
* @param {StringifyType} value - The stringify function to use
|
|
336
|
+
*/
|
|
337
|
+
set stringify(value) {
|
|
338
|
+
this._stringify = value;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Get the parse function used for converting strings to objects.
|
|
342
|
+
* @returns {ParseType} The current parse function
|
|
343
|
+
*/
|
|
344
|
+
get parse() {
|
|
345
|
+
return this._parse;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Set the parse function for converting strings to objects.
|
|
349
|
+
* @param {ParseType} value - The parse function to use
|
|
350
|
+
*/
|
|
351
|
+
set parse(value) {
|
|
352
|
+
this._parse = value;
|
|
313
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Get the Cacheable instance used for caching fetch operations.
|
|
356
|
+
* @returns {Cacheable} The current Cacheable instance
|
|
357
|
+
*/
|
|
314
358
|
get cache() {
|
|
315
359
|
return this._cache;
|
|
316
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Set the Cacheable instance for caching fetch operations.
|
|
363
|
+
* @param {Cacheable} value - The Cacheable instance to use for caching
|
|
364
|
+
*/
|
|
317
365
|
set cache(value) {
|
|
318
366
|
this._cache = value;
|
|
319
367
|
}
|
|
320
368
|
/**
|
|
321
|
-
* Get the current HTTP cache setting.
|
|
369
|
+
* Get the current HTTP cache policy setting.
|
|
322
370
|
* @returns {boolean} Whether HTTP cache semantics are enabled
|
|
323
371
|
*/
|
|
324
|
-
get
|
|
325
|
-
return this.
|
|
372
|
+
get httpCachePolicy() {
|
|
373
|
+
return this._httpCachePolicy;
|
|
326
374
|
}
|
|
327
375
|
/**
|
|
328
376
|
* Set whether to use HTTP cache semantics.
|
|
329
377
|
* @param {boolean} value - Enable or disable HTTP cache semantics
|
|
330
378
|
*/
|
|
331
|
-
set
|
|
332
|
-
this.
|
|
379
|
+
set httpCachePolicy(value) {
|
|
380
|
+
this._httpCachePolicy = value;
|
|
333
381
|
}
|
|
334
382
|
/**
|
|
335
383
|
* Fetch data from a URL with optional request options. Will use the cache that is already set in the instance.
|
|
336
384
|
*
|
|
337
|
-
* When `
|
|
385
|
+
* When `httpCachePolicy` is enabled (default), cache entries will have their TTL
|
|
338
386
|
* set based on HTTP cache headers (e.g., Cache-Control: max-age). When disabled,
|
|
339
387
|
* the default TTL from the Cacheable instance is used.
|
|
340
388
|
*
|
|
341
389
|
* @param {string} url The URL to fetch.
|
|
342
|
-
* @param {
|
|
390
|
+
* @param {Omit<FetchOptions, "cache">} options Optional request options.
|
|
343
391
|
* @returns {Promise<FetchResponse>} The response from the fetch.
|
|
344
392
|
*/
|
|
345
393
|
async fetch(url, options) {
|
|
346
394
|
const fetchOptions = {
|
|
347
395
|
...options,
|
|
348
396
|
cache: this._cache,
|
|
349
|
-
|
|
397
|
+
httpCachePolicy: this._httpCachePolicy
|
|
350
398
|
};
|
|
351
399
|
return fetch(url, fetchOptions);
|
|
352
400
|
}
|
|
353
401
|
/**
|
|
354
|
-
* Perform a GET request to a URL with optional request options.
|
|
402
|
+
* Perform a GET request to a URL with optional request options. By default caching is enabled on all requests. To
|
|
403
|
+
* disable set `options.caching` to false.
|
|
355
404
|
* @param {string} url The URL to fetch.
|
|
356
|
-
* @param {
|
|
405
|
+
* @param {NetFetchOptions} options Optional request options (method will be set to GET).
|
|
357
406
|
* @returns {Promise<DataResponse<T>>} The typed data and response from the fetch.
|
|
358
407
|
*/
|
|
359
408
|
async get(url, options) {
|
|
360
|
-
const
|
|
409
|
+
const fetchOptions = {
|
|
410
|
+
...options,
|
|
411
|
+
cache: this._cache,
|
|
412
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
413
|
+
method: "GET"
|
|
414
|
+
};
|
|
415
|
+
if (options?.caching !== void 0) {
|
|
416
|
+
delete fetchOptions.cache;
|
|
417
|
+
}
|
|
418
|
+
const response = await fetch(url, fetchOptions);
|
|
361
419
|
const text = await response.text();
|
|
362
420
|
let data;
|
|
421
|
+
const parseFn = options?.parse || this._parse;
|
|
363
422
|
try {
|
|
364
|
-
data =
|
|
423
|
+
data = parseFn(text);
|
|
365
424
|
} catch {
|
|
366
425
|
data = text;
|
|
367
426
|
}
|
|
@@ -376,10 +435,11 @@ var CacheableNet = class extends Hookified {
|
|
|
376
435
|
};
|
|
377
436
|
}
|
|
378
437
|
/**
|
|
379
|
-
* Perform a POST request to a URL with data and optional request options.
|
|
438
|
+
* Perform a POST request to a URL with data and optional request options. By default caching is not enabled. To enable it
|
|
439
|
+
* set `options.caching` to true. Note, setting caching to tru means it will not post if the data is the same.
|
|
380
440
|
* @param {string} url The URL to fetch.
|
|
381
441
|
* @param {unknown} data The data to send in the request body.
|
|
382
|
-
* @param {Omit<
|
|
442
|
+
* @param {Omit<NetFetchOptions, "method" | "body" >} options Optional request options (method and body will be set).
|
|
383
443
|
* @returns {Promise<DataResponse<T>>} The typed data and response from the fetch.
|
|
384
444
|
*/
|
|
385
445
|
async post(url, data, options) {
|
|
@@ -390,21 +450,28 @@ var CacheableNet = class extends Hookified {
|
|
|
390
450
|
} else if (data instanceof FormData || data instanceof URLSearchParams || data instanceof Blob) {
|
|
391
451
|
body = data;
|
|
392
452
|
} else {
|
|
393
|
-
|
|
453
|
+
const stringifyFn = options?.stringify || this._stringify;
|
|
454
|
+
body = stringifyFn(data);
|
|
394
455
|
if (!headers["Content-Type"] && !headers["content-type"]) {
|
|
395
456
|
headers["Content-Type"] = "application/json";
|
|
396
457
|
}
|
|
397
458
|
}
|
|
398
|
-
const
|
|
459
|
+
const fetchOptions = {
|
|
399
460
|
...options,
|
|
400
461
|
headers,
|
|
401
462
|
body,
|
|
463
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
402
464
|
method: "POST"
|
|
403
|
-
}
|
|
465
|
+
};
|
|
466
|
+
if (options?.caching === true) {
|
|
467
|
+
fetchOptions.cache = this._cache;
|
|
468
|
+
}
|
|
469
|
+
const response = await fetch(url, fetchOptions);
|
|
404
470
|
const text = await response.text();
|
|
405
471
|
let responseData;
|
|
472
|
+
const parseFn = options?.parse || this._parse;
|
|
406
473
|
try {
|
|
407
|
-
responseData =
|
|
474
|
+
responseData = parseFn(text);
|
|
408
475
|
} catch {
|
|
409
476
|
responseData = text;
|
|
410
477
|
}
|
|
@@ -419,20 +486,82 @@ var CacheableNet = class extends Hookified {
|
|
|
419
486
|
};
|
|
420
487
|
}
|
|
421
488
|
/**
|
|
422
|
-
* Perform a HEAD request to a URL with optional request options.
|
|
489
|
+
* Perform a HEAD request to a URL with optional request options. By default caching is enabled on all requests. To
|
|
490
|
+
* disable set `options.caching` to false.
|
|
423
491
|
* @param {string} url The URL to fetch.
|
|
424
|
-
* @param {
|
|
492
|
+
* @param {NetFetchOptions} options Optional request options (method will be set to HEAD).
|
|
425
493
|
* @returns {Promise<FetchResponse>} The response from the fetch (no body).
|
|
426
494
|
*/
|
|
427
495
|
async head(url, options) {
|
|
428
|
-
const
|
|
496
|
+
const fetchOptions = {
|
|
497
|
+
...options,
|
|
498
|
+
cache: this._cache,
|
|
499
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
500
|
+
method: "HEAD"
|
|
501
|
+
};
|
|
502
|
+
if (options?.caching !== void 0 && !options.caching) {
|
|
503
|
+
delete fetchOptions.cache;
|
|
504
|
+
}
|
|
505
|
+
const response = await fetch(url, fetchOptions);
|
|
429
506
|
return response;
|
|
430
507
|
}
|
|
431
508
|
/**
|
|
432
|
-
* Perform a
|
|
509
|
+
* Perform a PUT request to a URL with data and optional request options. By default caching is not enabled. To enable it
|
|
510
|
+
* set `options.caching` to true. Note, setting caching to true means it will not put if the data is the same.
|
|
511
|
+
* @param {string} url The URL to fetch.
|
|
512
|
+
* @param {unknown} data The data to send in the request body.
|
|
513
|
+
* @param {Omit<NetFetchOptions, 'method' | 'body'>} options Optional request options (method and body will be set).
|
|
514
|
+
* @returns {Promise<DataResponse<T>>} The typed data and response from the fetch.
|
|
515
|
+
*/
|
|
516
|
+
async put(url, data, options) {
|
|
517
|
+
let body;
|
|
518
|
+
const headers = { ...options?.headers };
|
|
519
|
+
if (typeof data === "string") {
|
|
520
|
+
body = data;
|
|
521
|
+
} else if (data instanceof FormData || data instanceof URLSearchParams || data instanceof Blob) {
|
|
522
|
+
body = data;
|
|
523
|
+
} else {
|
|
524
|
+
const stringifyFn = options?.stringify || this._stringify;
|
|
525
|
+
body = stringifyFn(data);
|
|
526
|
+
if (!headers["Content-Type"] && !headers["content-type"]) {
|
|
527
|
+
headers["Content-Type"] = "application/json";
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
const fetchOptions = {
|
|
531
|
+
...options,
|
|
532
|
+
headers,
|
|
533
|
+
body,
|
|
534
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
535
|
+
method: "PUT"
|
|
536
|
+
};
|
|
537
|
+
if (options?.caching === true) {
|
|
538
|
+
fetchOptions.cache = this._cache;
|
|
539
|
+
}
|
|
540
|
+
const response = await fetch(url, fetchOptions);
|
|
541
|
+
const text = await response.text();
|
|
542
|
+
let responseData;
|
|
543
|
+
const parseFn = options?.parse || this._parse;
|
|
544
|
+
try {
|
|
545
|
+
responseData = parseFn(text);
|
|
546
|
+
} catch {
|
|
547
|
+
responseData = text;
|
|
548
|
+
}
|
|
549
|
+
const newResponse = new Response(text, {
|
|
550
|
+
status: response.status,
|
|
551
|
+
statusText: response.statusText,
|
|
552
|
+
headers: response.headers
|
|
553
|
+
});
|
|
554
|
+
return {
|
|
555
|
+
data: responseData,
|
|
556
|
+
response: newResponse
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Perform a PATCH request to a URL with data and optional request options. By default caching is not enabled. To enable it
|
|
561
|
+
* set `options.caching` to true. Note, setting caching to true means it will not patch if the data is the same.
|
|
433
562
|
* @param {string} url The URL to fetch.
|
|
434
563
|
* @param {unknown} data The data to send in the request body.
|
|
435
|
-
* @param {Omit<
|
|
564
|
+
* @param {Omit<NetFetchOptions, 'method' | 'body'>} options Optional request options (method and body will be set).
|
|
436
565
|
* @returns {Promise<DataResponse<T>>} The typed data and response from the fetch.
|
|
437
566
|
*/
|
|
438
567
|
async patch(url, data, options) {
|
|
@@ -443,21 +572,28 @@ var CacheableNet = class extends Hookified {
|
|
|
443
572
|
} else if (data instanceof FormData || data instanceof URLSearchParams || data instanceof Blob) {
|
|
444
573
|
body = data;
|
|
445
574
|
} else {
|
|
446
|
-
|
|
575
|
+
const stringifyFn = options?.stringify || this._stringify;
|
|
576
|
+
body = stringifyFn(data);
|
|
447
577
|
if (!headers["Content-Type"] && !headers["content-type"]) {
|
|
448
578
|
headers["Content-Type"] = "application/json";
|
|
449
579
|
}
|
|
450
580
|
}
|
|
451
|
-
const
|
|
581
|
+
const fetchOptions = {
|
|
452
582
|
...options,
|
|
453
583
|
headers,
|
|
454
584
|
body,
|
|
585
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
455
586
|
method: "PATCH"
|
|
456
|
-
}
|
|
587
|
+
};
|
|
588
|
+
if (options?.caching === true) {
|
|
589
|
+
fetchOptions.cache = this._cache;
|
|
590
|
+
}
|
|
591
|
+
const response = await fetch(url, fetchOptions);
|
|
457
592
|
const text = await response.text();
|
|
458
593
|
let responseData;
|
|
594
|
+
const parseFn = options?.parse || this._parse;
|
|
459
595
|
try {
|
|
460
|
-
responseData =
|
|
596
|
+
responseData = parseFn(text);
|
|
461
597
|
} catch {
|
|
462
598
|
responseData = text;
|
|
463
599
|
}
|
|
@@ -472,10 +608,11 @@ var CacheableNet = class extends Hookified {
|
|
|
472
608
|
};
|
|
473
609
|
}
|
|
474
610
|
/**
|
|
475
|
-
* Perform a DELETE request to a URL with optional data and request options.
|
|
611
|
+
* Perform a DELETE request to a URL with optional data and request options. By default caching is not enabled. To enable it
|
|
612
|
+
* set `options.caching` to true. Note, setting caching to true means it will not delete if the data is the same.
|
|
476
613
|
* @param {string} url The URL to fetch.
|
|
477
614
|
* @param {unknown} data Optional data to send in the request body.
|
|
478
|
-
* @param {Omit<
|
|
615
|
+
* @param {Omit<NetFetchOptions, 'method' | 'body'>} options Optional request options (method and body will be set).
|
|
479
616
|
* @returns {Promise<DataResponse<T>>} The typed data and response from the fetch.
|
|
480
617
|
*/
|
|
481
618
|
async delete(url, data, options) {
|
|
@@ -487,22 +624,29 @@ var CacheableNet = class extends Hookified {
|
|
|
487
624
|
} else if (data instanceof FormData || data instanceof URLSearchParams || data instanceof Blob) {
|
|
488
625
|
body = data;
|
|
489
626
|
} else {
|
|
490
|
-
|
|
627
|
+
const stringifyFn = options?.stringify || this._stringify;
|
|
628
|
+
body = stringifyFn(data);
|
|
491
629
|
if (!headers["Content-Type"] && !headers["content-type"]) {
|
|
492
630
|
headers["Content-Type"] = "application/json";
|
|
493
631
|
}
|
|
494
632
|
}
|
|
495
633
|
}
|
|
496
|
-
const
|
|
634
|
+
const fetchOptions = {
|
|
497
635
|
...options,
|
|
498
636
|
headers,
|
|
499
637
|
body,
|
|
638
|
+
httpCachePolicy: this._httpCachePolicy,
|
|
500
639
|
method: "DELETE"
|
|
501
|
-
}
|
|
640
|
+
};
|
|
641
|
+
if (options?.caching === true) {
|
|
642
|
+
fetchOptions.cache = this._cache;
|
|
643
|
+
}
|
|
644
|
+
const response = await fetch(url, fetchOptions);
|
|
502
645
|
const text = await response.text();
|
|
503
646
|
let responseData;
|
|
647
|
+
const parseFn = options?.parse || this._parse;
|
|
504
648
|
try {
|
|
505
|
-
responseData =
|
|
649
|
+
responseData = parseFn(text);
|
|
506
650
|
} catch {
|
|
507
651
|
responseData = text;
|
|
508
652
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cacheable/net",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "High Performance Network Caching for Node.js with fetch, request, http 1.1, and http 2 support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"private": false,
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@biomejs/biome": "^2.2.
|
|
24
|
+
"@biomejs/biome": "^2.2.4",
|
|
25
25
|
"@faker-js/faker": "^10.0.0",
|
|
26
26
|
"@types/http-cache-semantics": "^4.0.4",
|
|
27
|
-
"@types/node": "^24.
|
|
27
|
+
"@types/node": "^24.5.2",
|
|
28
28
|
"@vitest/coverage-v8": "^3.2.4",
|
|
29
29
|
"rimraf": "^6.0.1",
|
|
30
30
|
"tsup": "^8.5.0",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"vitest": "^3.2.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"hookified": "^1.12.
|
|
35
|
+
"hookified": "^1.12.1",
|
|
36
36
|
"http-cache-semantics": "^4.2.0",
|
|
37
|
-
"undici": "^7.
|
|
38
|
-
"cacheable": "^2.0.
|
|
37
|
+
"undici": "^7.16.0",
|
|
38
|
+
"cacheable": "^2.0.3"
|
|
39
39
|
},
|
|
40
40
|
"keywords": [
|
|
41
41
|
"cacheable",
|