Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
@americanexpress/fetch-enhancers
Advanced tools
A library of middleware for enhancing Fetch.
Want to get paid for your contributions to @americanexpress/fetch-enhancers
?
Send your resume to oneamex.careers@aexp.com
npm install --save @americanexpress/fetch-enhancers
Each fetch enhancer follows the same pattern:
fetchEnhancer(configuration)
fetchEnhancer(configuration)(fetch)
import { createTimeoutFetch } from '@americanexpress/fetch-enhancers';
createTimeoutFetch
makes use of the AbortController to abort requests which exceed the given time limit.
createTimeoutFetch
takes a single argument which sets the default timeout.
const enhancedTimeoutFetch = createTimeoutFetch(6e3)(fetch);
When called, the enhanced fetch will accept an additional option, timeout
, allowing for the
default timeout value to be overridden for a single request.
const slowRequest = timeoutFetch('https://example.com/some-slow-api', { timeout: 10e3 });
import { createTimeoutFetch } from '@americanexpress/fetch-enhancers';
// set your default timeout
const timeoutFetch = createTimeoutFetch(6e3)(fetch);
// Then use timeoutFetch as you would normally
const request = timeoutFetch('https://example.com');
request.then((response) => response.json())
.then((data) => {
console.log(data);
});
// each request can override the default timeout
const fastRequest = timeoutFetch('https://example.com/fast', { timeout: 1e3 });
import { createRetryFetch } from '@americanexpress/fetch-enhancers';
createRetryFetch
accepts the an object with the following configuration: an optional maxRetry (default 3), and an optional back off strategy function:
const enhancedRetryFetch = createRetryFetch()(fetch);
Optional retry count and back off strategy function that accepts the current retry count:
const enhancedRetryFetch = createRetryFetch({
maxRetry: 5,
backoffStrategy: (n) => new Promise((res) => { setTimeout(res, n * 1000); }),
})(fetch);
import { createRetryFetch } from '@americanexpress/fetch-enhancers';
const retryFetch = createRetryFetch()(createTimeoutFetch(5e3)(fetch));
// Then use retryFetch as you would normally
const request = retryFetch('https://example.com');
request.then((response) => response.json())
.then((data) => {
// do something with data
});
import { createBrowserLikeFetch } from '@americanexpress/fetch-enhancers';
createBrowserLikeFetch
is for use on the server only. It enables the forwarding of
cookies and headers from the request made to the host server to trusted outbound requests made during
a server side render. Cookies which are returned are stored for the life of the host servers requests
allowing those cookies to be included, when valid, on subsequent requests.
createBrowserLikeFetch
accepts the following named arguments:
headers
Object containing any headers to be included on fetch requests.
An example of how you could build the headers
const parseHeaders = (req) => ({
Referer: url.format({
protocol: req.protocol,
hostname: req.hostname,
pathname: req.path,
}),
cookie: req.headers.cookie,
});
const headers = parseHeaders(req);
const fetchWithRequestHeaders = createBrowserLikeFetch({
headers,
hostname: req.hostname,
res, // Express response
trustedURLs: [/^https:\/\/(www\.){0,1}(.*\.)example\.com[#/:?]{0,1}/],
})(mockFetch);
hostname
Hostname which should be derived from the Host HTTP header. Used to determine if set setCookie
will be called. If using Express this can be retrieved from the req
object.
res
Typically this would be an Express response object. createBrowserLikeFetch
makes use of the cookie function to set cookies on the response.
If you wish to provide your own function to set cookies, use setCookie.
res.cookie()
function provided by express requiresthis
to be set to the context of the express middleware.
setCookie
This takes precedence over res.cookie
provided in the res
argument.
setCookie(name, value [, options])
A callback function invoked when a fetch response contains cookies with a domain which matches to the given hostname. This can be used to set the cookie on a response object.
setCookie
is called with the same options as though it's the Express response cookie function.
If you are passing in your own setCookie function it is important to note that the maxAge
option will be in milliseconds.
If desired you can use setCookie
to add additional checks or modify options passed to req.cookie
.
const buildStringURIEncodingSetCookie = (res) => (name, value, options) => {
res.cookie(name, value, { ...options, encode: String });
};
const fetchWithRequestHeaders = createBrowserLikeFetch({
headers,
hostname: req.hostname,
setCookie: (name, value, options) => res.cookie(name, value, {
...options, encode: String,
}),
trustedURLs: [/^https:\/\/(www\.){0,1}(.*\.)example\.com[#/:?]{0,1}/],
})(mockFetch);
trustedURLs
A list of regular expressions used to test the first argument given to fetch when making a request. If the test is successful the enhanced fetch will include provided cookies.
const trustedURLs = [
/^https:\/\/api\.example\.com[#/:?]{0,1}/,
/^https:\/\/another\.example\.com[#/:?]{0,1}/,
// or, more permissively all subdomains, including none
/^https:\/\/(www\.){0,1}(.*\.)example\.com[#/:?]{0,1}/,
];
As these are regular expressions, be careful to consider values that you also do not want matched (ex: https://example.com.evil.tld/pwned
).
trustedDomains
Renamed to trustedURLs
. Usage of trustedDomains
is deprecated, but values are added to those of trustedURLs
until the next breaking version.
const parseHeaders = (req) => ({
Referer: url.format({
protocol: req.protocol,
hostname: req.hostname,
pathname: req.path,
}),
cookie: req.headers.cookie,
'some-header': req.headers['some-header'] || '1234',
});
const fetchWithRequestHeaders = createBrowserLikeFetch({
headers: parseHeaders(req),
hostname: req.hostname,
res, // Express response
trustedURLs: [/^https:\/\/(www\.){0,1}(.*\.)example\.com[#/:?]{0,1}/],
})(mockFetch);
fetchWithRequestHeaders('https://example.com', {
credentials: 'include',
});
You can chain together multiple enhancers to build a specific enhanced fetch client
import { createTimeoutFetch } from '@americanexpress/fetch-enhancers';
import { yourFetch } from './safeFetch';
const timeoutFetch = createTimeoutFetch(6e3)(fetch);
const myTimeoutFetch = yourFetch(/* options for configuring yourFetch */)(timeoutFetch);
// use the enhanced fetch as you would normally
const response = myTimeoutFetch('https://example.com');
You can also use Redux's compose
function
import { compose } from 'redux';
import { createTimeoutFetch } from '@americanexpress/fetch-enhancers';
import { yourFetch } from './safeFetch';
const enhancedFetch = compose(
yourFetch(),
createTimeoutFetch(6e3)
)(fetch);
// Then use the enhanced fetch as you would normally
const request = enhancedFetch('https://example.com');
request.then((response) => response.json())
.then((data) => {
// do something with data
});
Each enhancer must return a function which accepts fetch
as a single argument.
const strictCookieFetch = ({ allowSameOrigin }) => (nextFetch) => {
(url, arguments_) => nextFetch(url, {
...arguments_,
// use config arg allowSameOrigin
credentials: allowSameOrigin ? 'same-origin' : 'omit',
});
};
const safeFetch = strictCookieFetch()(fetch);
We welcome Your interest in the American Express Open Source Community on Github. Any Contributor to any Open Source Project managed by the American Express Open Source Community must accept and sign an Agreement indicating agreement to the terms below. Except for the rights granted in this Agreement to American Express and to recipients of software distributed by American Express, You reserve all right, title, and interest, if any, in and to Your Contributions. Please fill out the Agreement.
Please feel free to open pull requests and see CONTRIBUTING.md to learn how to get started contributing.
Any contributions made under this project will be governed by the Apache License 2.0.
This project adheres to the American Express Community Guidelines. By participating, you are expected to honor these guidelines.
FAQs
Set of enhancers to extend fetch
The npm package @americanexpress/fetch-enhancers receives a total of 0 weekly downloads. As such, @americanexpress/fetch-enhancers popularity was classified as not popular.
We found that @americanexpress/fetch-enhancers demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.