make-fetch-happen
Advanced tools
Comparing version
{ | ||
"name": "make-fetch-happen", | ||
"version": "8.0.14", | ||
"version": "11.1.1", | ||
"description": "Opinionated, caching, retrying fetch client", | ||
"main": "index.js", | ||
"main": "lib/index.js", | ||
"files": [ | ||
"*.js", | ||
"lib", | ||
"utils" | ||
"bin/", | ||
"lib/" | ||
], | ||
"scripts": { | ||
"preversion": "npm t", | ||
"postversion": "npm publish", | ||
"prepublishOnly": "git push --follow-tags", | ||
"test": "tap test/*.js", | ||
"test": "tap", | ||
"posttest": "npm run lint", | ||
"eslint": "eslint", | ||
"lint": "npm run eslint -- *.js utils test", | ||
"lintfix": "npm run lint -- --fix" | ||
"lint": "eslint \"**/*.js\"", | ||
"lintfix": "npm run lint -- --fix", | ||
"postlint": "template-oss-check", | ||
"snap": "tap", | ||
"template-oss-apply": "template-oss-apply --force" | ||
}, | ||
"repository": "https://github.com/npm/make-fetch-happen", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/npm/make-fetch-happen.git" | ||
}, | ||
"keywords": [ | ||
@@ -31,43 +33,47 @@ "http", | ||
], | ||
"author": { | ||
"name": "Kat Marchán", | ||
"email": "kzm@zkat.tech", | ||
"twitter": "maybekatz" | ||
}, | ||
"author": "GitHub Inc.", | ||
"license": "ISC", | ||
"dependencies": { | ||
"agentkeepalive": "^4.1.3", | ||
"cacache": "^15.0.5", | ||
"http-cache-semantics": "^4.1.0", | ||
"http-proxy-agent": "^4.0.1", | ||
"agentkeepalive": "^4.2.1", | ||
"cacache": "^17.0.0", | ||
"http-cache-semantics": "^4.1.1", | ||
"http-proxy-agent": "^5.0.0", | ||
"https-proxy-agent": "^5.0.0", | ||
"is-lambda": "^1.0.1", | ||
"lru-cache": "^6.0.0", | ||
"minipass": "^3.1.3", | ||
"minipass-collect": "^1.0.2", | ||
"minipass-fetch": "^1.3.2", | ||
"lru-cache": "^7.7.1", | ||
"minipass": "^5.0.0", | ||
"minipass-fetch": "^3.0.0", | ||
"minipass-flush": "^1.0.5", | ||
"minipass-pipeline": "^1.2.4", | ||
"negotiator": "^0.6.3", | ||
"promise-retry": "^2.0.1", | ||
"socks-proxy-agent": "^5.0.0", | ||
"ssri": "^8.0.0" | ||
"socks-proxy-agent": "^7.0.0", | ||
"ssri": "^10.0.0" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^7.14.0", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-promise": "^4.2.1", | ||
"eslint-plugin-standard": "^5.0.0", | ||
"mkdirp": "^1.0.4", | ||
"nock": "^11.9.1", | ||
"npmlog": "^4.1.2", | ||
"require-inject": "^1.4.2", | ||
"rimraf": "^2.7.1", | ||
"@npmcli/eslint-config": "^4.0.0", | ||
"@npmcli/template-oss": "4.14.1", | ||
"nock": "^13.2.4", | ||
"safe-buffer": "^5.2.1", | ||
"standard-version": "^7.1.0", | ||
"tap": "^14.11.0" | ||
"standard-version": "^9.3.2", | ||
"tap": "^16.0.0" | ||
}, | ||
"engines": { | ||
"node": ">= 10" | ||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0" | ||
}, | ||
"tap": { | ||
"color": 1, | ||
"files": "test/*.js", | ||
"check-coverage": true, | ||
"timeout": 60, | ||
"nyc-arg": [ | ||
"--exclude", | ||
"tap-snapshots/**" | ||
] | ||
}, | ||
"templateOSS": { | ||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", | ||
"version": "4.14.1", | ||
"publish": "true" | ||
} | ||
} |
119
README.md
@@ -23,4 +23,5 @@ # make-fetch-happen | ||
* [`make-fetch-happen` options](#extra-options) | ||
* [`opts.cacheManager`](#opts-cache-manager) | ||
* [`opts.cachePath`](#opts-cache-path) | ||
* [`opts.cache`](#opts-cache) | ||
* [`opts.cacheAdditionalHeaders`](#opts-cache-additional-headers) | ||
* [`opts.proxy`](#opts-proxy) | ||
@@ -33,2 +34,3 @@ * [`opts.noProxy`](#opts-no-proxy) | ||
* [`opts.integrity`](#opts-integrity) | ||
* [`opts.dns`](#opts-dns) | ||
* [Message From Our Sponsors](#wow) | ||
@@ -40,3 +42,3 @@ | ||
const fetch = require('make-fetch-happen').defaults({ | ||
cacheManager: './my-cache' // path where cache will be written (and read) | ||
cachePath: './my-cache' // path where cache will be written (and read) | ||
}) | ||
@@ -68,3 +70,2 @@ | ||
* Built-in request caching following full HTTP caching rules (`Cache-Control`, `ETag`, `304`s, cache fallback on error, etc). | ||
* Customize cache storage with any [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache)-compliant `Cache` instance. Cache to Redis! | ||
* Node.js Stream support | ||
@@ -74,2 +75,3 @@ * Transparent gzip and deflate support | ||
* Literally punches nazis | ||
* Built in DNS cache | ||
* (PENDING) Range request caching and resuming | ||
@@ -111,3 +113,3 @@ | ||
const fetch = require('make-fetch-happen').defaults({ | ||
cacheManager: './my-local-cache' | ||
cachePath: './my-local-cache' | ||
}) | ||
@@ -145,4 +147,5 @@ | ||
* [`opts.cacheManager`](#opts-cache-manager) - Cache target to read/write | ||
* [`opts.cachePath`](#opts-cache-path) - Cache target to read/write | ||
* [`opts.cache`](#opts-cache) - `fetch` cache mode. Controls cache *behavior*. | ||
* [`opts.cacheAdditionalHeaders`](#opts-cache-additional-headers) - Store additional headers in the cache | ||
* [`opts.proxy`](#opts-proxy) - Proxy agent | ||
@@ -156,13 +159,8 @@ * [`opts.noProxy`](#opts-no-proxy) - Domain segments to disable proxying for. | ||
* [`opts.integrity`](#opts-integrity) - [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) metadata. | ||
* [`opts.dns`](#opts-dns) - DNS cache options | ||
#### <a name="opts-cache-manager"></a> `> opts.cacheManager` | ||
#### <a name="opts-cache-path"></a> `> opts.cachePath` | ||
Either a `String` or a `Cache`. If the former, it will be assumed to be a `Path` to be used as the cache root for [`cacache`](https://npm.im/cacache). | ||
A string `Path` to be used as the cache root for [`cacache`](https://npm.im/cacache). | ||
If an object is provided, it will be assumed to be a compliant [`Cache` instance](https://developer.mozilla.org/en-US/docs/Web/API/Cache). Only `Cache.match()`, `Cache.put()`, and `Cache.delete()` are required. Options objects will not be passed in to `match()` or `delete()`. | ||
By implementing this API, you can customize the storage backend for make-fetch-happen itself -- for example, you could implement a cache that uses `redis` for caching, or simply keeps everything in memory. Most of the caching logic exists entirely on the make-fetch-happen side, so the only thing you need to worry about is reading, writing, and deleting, as well as making sure `fetch.Response` objects are what gets returned. | ||
You can refer to `cache.js` in the make-fetch-happen source code for a reference implementation. | ||
**NOTE**: Requests will not be cached unless their response bodies are consumed. You will need to use one of the `res.json()`, `res.buffer()`, etc methods on the response, or drain the `res.body` stream, in order for it to be written. | ||
@@ -174,3 +172,5 @@ | ||
* `X-Local-Cache-Key`: Unique cache entry key for this response | ||
* `X-Local-Cache-Mode`: Always `stream` to indicate how the response was read from cacache | ||
* `X-Local-Cache-Hash`: Specific integrity hash for the cached entry | ||
* `X-Local-Cache-Status`: One of `miss`, `hit`, `stale`, `revalidated`, `updated`, or `skip` to signal how the response was created | ||
* `X-Local-Cache-Time`: UTCString of the cache insertion time for the entry | ||
@@ -193,52 +193,9 @@ | ||
fetch('https://registry.npmjs.org/make-fetch-happen', { | ||
cacheManager: './my-local-cache' | ||
cachePath: './my-local-cache' | ||
}) // -> 200-level response will be written to disk | ||
fetch('https://npm.im/cacache', { | ||
cacheManager: new MyCustomRedisCache(process.env.PORT) | ||
}) // -> 200-level response will be written to redis | ||
``` | ||
A possible (minimal) implementation for `MyCustomRedisCache`: | ||
```javascript | ||
const bluebird = require('bluebird') | ||
const redis = require("redis") | ||
bluebird.promisifyAll(redis.RedisClient.prototype) | ||
class MyCustomRedisCache { | ||
constructor (opts) { | ||
this.redis = redis.createClient(opts) | ||
} | ||
match (req) { | ||
return this.redis.getAsync(req.url).then(res => { | ||
if (res) { | ||
const parsed = JSON.parse(res) | ||
return new fetch.Response(parsed.body, { | ||
url: req.url, | ||
headers: parsed.headers, | ||
status: 200 | ||
}) | ||
} | ||
}) | ||
} | ||
put (req, res) { | ||
return res.buffer().then(body => { | ||
return this.redis.setAsync(req.url, JSON.stringify({ | ||
body: body, | ||
headers: res.headers.raw() | ||
})) | ||
}).then(() => { | ||
// return the response itself | ||
return res | ||
}) | ||
} | ||
'delete' (req) { | ||
return this.redis.unlinkAsync(req.url) | ||
} | ||
} | ||
``` | ||
#### <a name="opts-cache"></a> `> opts.cache` | ||
This option follows the standard `fetch` API cache option. This option will do nothing if [`opts.cacheManager`](#opts-cache-manager) is null. The following values are accepted (as strings): | ||
This option follows the standard `fetch` API cache option. This option will do nothing if [`opts.cachePath`](#opts-cache-path) is null. The following values are accepted (as strings): | ||
@@ -258,3 +215,3 @@ * `default` - Fetch will inspect the HTTP cache on the way to the network. If there is a fresh response it will be used. If there is a stale response a conditional request will be created, and a normal request otherwise. It then updates the HTTP cache with the response. If the revalidation request fails (for example, on a 500 or if you're offline), the stale response will be returned. | ||
const fetch = require('make-fetch-happen').defaults({ | ||
cacheManager: './my-cache' | ||
cachePath: './my-cache' | ||
}) | ||
@@ -278,2 +235,30 @@ | ||
#### <a name="opts-cache-additional-headers"></a> `> opts.cacheAdditionalHeaders` | ||
The following headers are always stored in the cache when present: | ||
- `cache-control` | ||
- `content-encoding` | ||
- `content-language` | ||
- `content-type` | ||
- `date` | ||
- `etag` | ||
- `expires` | ||
- `last-modified` | ||
- `link` | ||
- `location` | ||
- `pragma` | ||
- `vary` | ||
This option allows a user to store additional custom headers in the cache. | ||
##### Example | ||
```javascript | ||
fetch('https://registry.npmjs.org/make-fetch-happen', { | ||
cacheAdditionalHeaders: ['my-custom-header'], | ||
}) | ||
``` | ||
#### <a name="opts-proxy"></a> `> opts.proxy` | ||
@@ -345,3 +330,2 @@ | ||
* `getaddrinfo ENOTFOUND` and will be assumed to be either an unreachable domain or the user will be assumed offline. If a response is cached, it will be returned immediately. | ||
* `ECONNRESET` currently has no support for restarting. It will eventually be supported but requires a bit more juggling due to streaming. | ||
@@ -383,3 +367,3 @@ If `opts.retry` is `false`, it is equivalent to `{retries: 0}` | ||
A function called whenever a retry is attempted. | ||
A function called with the response or error which caused the retry whenever one is attempted. | ||
@@ -390,4 +374,4 @@ ##### Example | ||
fetch('https://flaky.site.com', { | ||
onRetry() { | ||
console.log('we will retry!') | ||
onRetry(cause) { | ||
console.log('we will retry because of', cause) | ||
} | ||
@@ -415,6 +399,9 @@ }) | ||
### <a name="wow"></a> Message From Our Sponsors | ||
#### <a name="opts-dns"></a> `> opts.dns` | ||
 | ||
An object that provides options for the built-in DNS cache. The following options are available: | ||
 | ||
Note: Due to limitations in the current proxy agent implementation, users of proxies will not benefit from the DNS cache. | ||
* `ttl`: Milliseconds to keep cached DNS responses for. Defaults to `5 * 60 * 1000` (5 minutes) | ||
* `lookup`: A custom lookup function, see [`dns.lookup()`](https://nodejs.org/api/dns.html#dnslookuphostname-options-callback) for implementation details. Defaults to `require('dns').lookup`. |
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
6
-53.85%15
15.38%1153
26.7%6
-14.29%61201
-17.4%392
-3.21%8
14.29%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated