Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@jemmyphan/frisbee
Advanced tools
Modern fetch-based alternative to axios/superagent/request. Great for React Native.
:heart: Love this project? Support @niftylettuce's FOSS on Patreon or PayPal :unicorn:
Modern fetch-based alternative to axios/superagent/request. Great for React Native.
New in v2.0.4++:
baseURI
is now optional and you can passraw: true
as a global or request-based option to get the rawfetch()
response (e.g. if you want to useres.arrayBuffer()
or any other method manually).
Install the required package (note that react-native
provides us with a fetch
implementation):
npm install --save frisbee
Require the package:
const Frisbee = require('frisbee');
Install the required packages:
npm:
# optional (to support older browsers):
npm install es6-promise
# required (this package):
npm install frisbee
yarn:
# optional (to support older browsers):
yarn add es6-promise
# required (this package):
yarn add frisbee
Require it, set default options, and make some requests:
// add optional support for older browsers
const es6promise = require('es6-promise');
es6promise.polyfill();
// require the module
const Frisbee = require('frisbee');
// create a new instance of Frisbee
const api = new Frisbee({
baseURI: 'https://api.startup.com', // optional
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
// this is just an example of an anonymous
// function invoked immediately with async/await
(async () => {
// log in to our API with a user/pass
try {
// make the request
let res = await api.post('/v1/login');
console.log('response', res.body);
// handle HTTP or API errors
if (res.err) throw res.err;
// set basic auth headers for all
// future API requests we make
api.auth(res.body.api_token);
// now let's post a message to our API
res = await api.post('/v1/messages', { body: 'Hello' });
console.log('response', res.body);
// handle HTTP or API errors
if (res.err) throw res.err;
// now let's get a list of messages filtered by page and limit
res = await api.get('/v1/messages', {
body: {
limit: 10,
page: 2
}
});
// handle HTTP or API errors
if (res.err) throw res.err;
// now let's logout
res = api.post('/v1/logout');
console.log('response', res.body);
// handle HTTP or API errors
if (res.err) throw res.err;
// unset auth now since we logged out
api.auth();
// for more information on `fetch` headers and
// how to send and expect various types of data:
// <https://github.com/github/fetch>
} catch (err) {
throw err;
}
})();
If you're using node-fetch
, you need node-fetch@v1.5.3+
to use form-data
with files properly (due to bitinn/node-fetch#102)
If you experience form file upload issues, please see facebook/react-native#7564 (comment).
const Frisbee = require('frisbee');
Frisbee
is a function that optionally accepts an argument options
, which is an object full of options for constructing your API instance.
Frisbee
- accepts an options
object, with the following accepted options:
baseURI
- the default URI to use as a prefix for all HTTP requests (optional as of v2.0.4+)
If your API server is running on http://localhost:8080
, then use that as the value for this option
If you use React Native, then you most likely want to set baseURI
as follows (e.g. making use of __DEV__
global variable):
const api = new Frisbee({
baseURI: __DEV__
? process.env.API_BASE_URI || 'http://localhost:8080'
: 'https://api.startup.com'
});
You could also set API_BASE_URI
as an environment variable, and then set the value of this option to process.env.API_BASE_URI
(e.g. API_BASE_URI=http://localhost:8080 node app
)
Using React Native? You might want to read this article about automatic IP configuration.
headers
- an object containing default headers to send with every request
"Accept"
header to "application/json"
and the "Content-Type"
header to "application/json"
auth
- will call the auth()
function below and set it as a default
arrayFormat
- how to stringify array in passed body. See qs for available formats
raw
- return a raw fetch response (new as of v2.0.4+)
Upon being invoked, Frisbee
returns an object with the following chainable methods:
api.auth(creds)
- helper function that sets BasicAuth headers, and it accepts user
and pass
arguments
creds
user and pass as an array, arguments, or string: ([user, pass])
, (user, pass)
, or ("user:pass")
, so you shouldn't have any problems!user
and pass
arguments, then it removes any previously set BasicAuth headers from prior auth()
callsuser
, then it will set pass
to an empty string ''
):
then it will assume you are trying to set BasicAuth headers using your own user:pass
stringuser
and pass
anyways)api.jwt(token)
- helper function that sets a JWT Bearer header. It accepts the jwt_token
as a single string argument. If you simply invoke the function null
as the argument for your token, it will remove JWT headers.
All exposed HTTP methods return a Promise, and they require a path
string, and accept an optional options
object:
Accepted method arguments:
path
required - the path for the HTTP request (e.g. /v1/login
, will be prefixed with the value of baseURI
if set)
options
optional - an object containing options, such as header values, a request body, form data, or a querystring to send along with the request. For the GET
method (and the DELETE
method as of version 1.3.0
), body
data will be encoded in the query string.
Here are a few examples (you can override/merge your set default headers as well per request):
To set a custom header value of X-Reply-To
on a POST
request:
const res = await api.post('/messages', {
headers: {
'X-Reply-To': '7s9inuna748y4l1azchi'
}
});
raw
optional - will override a global raw
option if set, and if it is true
it will return a raw fetch
response (new as of v2.0.4+)
List of available HTTP methods:
api.get(path, options)
- GETapi.head(path, options)
- HEAD (does not currently work - see tests)api.post(path, options)
- POSTapi.put(path, options)
- PUTapi.del(path, options)
- DELETEapi.options(path, options)
- OPTIONS (does not currently work - see tests)api.patch(path, options)
- PATCHNote that you can chain the auth
method and a HTTP method together:
const res = await api.auth('foo:bar').get('/');
interceptor
- object that can be used to manipulate request and response interceptors. It has the following methods:
api.interceptor.register(interceptor)
:
Accepts an interceptor object that can have one or more of the following functions
{
request: function (path, options) {
// Read/Modify the path or options
// ...
return [path, options];
},
requestError: function (err) {
// Handle an error occured in the request method
// ...
return Promise.reject(err);
},
response: function (response) {
// Read/Modify the response
// ...
return response;
},
responseError: function (err) {
// Handle error occured in api/response methods
return Promise.reject(err);
}
the register
method returns an unregister()
function so that you can unregister the added interceptor.
api.interceptor.unregister(interceptor)
:
Accepts the interceptor reference that you want to delete.
api.interceptor.clear()
:
Removes all the added interceptors.
Note that when interceptors are added in the order ONE->TWO->THREE:
request
/requestError
functions will run in the same order ONE->TWO->THREE
.response
/responseError
functions will run in reversed order THREE->TWO->ONE
.Simply set its value to null
, ''
, or undefined
– and it will be unset and removed from the headers sent with your request.
A common use case for this is when you are attempting to use FormData
and need the content boundary automatically added.
This is due to a bug with setting the boundary. For more information and temporary workaround if you are affected please see facebook/react-native#7564 (comment).
As of version 1.0.0
we have dropped support for callbacks, it now only supports Promises.
fetch
methodIt is a WHATWG browser API specification. You can read more about at the following links:
fetch
yetYes, a lot of browsers are now supporting it! See this reference for more information http://caniuse.com/#feat=fetch.
fetch
yet, is there a polyfillYes you can use the fetch
method (polyfill) from whatwg-fetch or node-fetch.
By default, React Native already has a built-in fetch
out of the box!
fetch
support older browsersYes, but you'll need a promise polyfill for older browsers.
Use this package as a universal API wrapper for integrating your API in your client-side or server-side projects.
It's a better working alternative (and with less headaches; at least for me) – for talking to your API – than superagent and the default fetch Network method provide.
Use it for projects in Node, React, Angular, React Native, ...
It supports and is tested for both client-side usage (e.g. with Bower, Browserify, or Webpack, with whatwg-fetch
) and also server-side (with node-fetch
).
superagent
or fetch
See Background for more information.
See Lad as a great starting point, and read this article about building Node.js API's with authentication.
File an issue on GitHub and we'll try our best help you out.
This package is tested to work with whatwg-fetch
and node-fetch
.
This means that it is compatible for both client-side and server-side usage.
npm install
npm run watch
to watch the src
directory for changessrc
directory/test/
if you add more stuffnpm test
when you're doneThe docs suggest that you use superagent
with React Native, but in our experience it did not work properly, therefore we went with the next best solution, the Github fetch
API polyfill included with React Native. After having several issues trying to use fetch
and writing our own API wrapper for a project with it (and running into roadblocks along the way) – we decided to publish this.
Here were the issues we discovered/filed related to this:
We know that solutions like superagent
exist, but they don't seem to work well with React Native (which was our use case for this package).
In addition, the authors of WHATWG's fetch API only support throwing errors instead of catching them and bubbling them up to the callback/promise (for example, with Frisbee any HTTP or API errors are found in the res.err
object).
Therefore we created frisbee
to serve as our API glue, and hopefully it'll serve as yours too.
Name | Website |
---|---|
Nick Baugh | http://niftylettuce.com/ |
Alexis Tyler | |
Assem-Hafez | |
Jordan Denison | |
James | |
Sampsa Saarela | |
Julien Moutte | |
Charles Soetan | |
Kesha Antonov | |
Ben Turley | |
Richard Evans | |
Hawken Rives | |
Fernando Montoya | |
Brent Vatne | |
Hosmel Quintana | |
Kyle Kirbatski |
fetch-api
, and frisbee
was surprisingly available on npm)FAQs
Modern fetch-based alternative to axios/superagent/request. Great for React Native.
We found that @jemmyphan/frisbee demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.