Skip to content

Instantly share code, notes, and snippets.

@developit
Created April 16, 2020 21:40
Show Gist options
  • Save developit/2f95f04def1c4dd034164f81b55e22b3 to your computer and use it in GitHub Desktop.
Save developit/2f95f04def1c4dd034164f81b55e22b3 to your computer and use it in GitHub Desktop.
export default (function create(options = {}) {
const client = {
headers: options.headers || {},
create
};
const events = {};
client.emit = (type, e) => {
events[type] &&
events[type].slice().map(fn => {
fn(e);
});
};
client.on = (type, fn) => {
(events[type] || (events[type] = [])).push(fn);
};
client.off = (type, fn) => {
events[type] && events[type].splice(events[type].indexOf(fn) >>> 0, 1);
};
client.bind = (url, config) => (...args) => client.request(
url.replace(/:[a-z]+/g, (s, f) => encodeURIComponent(args.shift())),
args.pop(),
config
);
client.request = (url, body, config) => {
let method;
url = url.replace(/^([A-Z]+) /,(s,m)=>method=m&&'');
const req = Object.assign({}, config, {
method,
url: (options.url || '') + url,
headers: Object.assign({}, client.headers, config && config.headers)
});
if (body) {
if (method > 'I') {
req.body = body;
if (typeof (req.body = body) == 'object') {
req.body = JSON.stringify(body);
req.headers['Content-Type'] = 'application/json';
}
} else {
req.url += '?' + new URLSearchParams(body);
}
}
client.emit('before', req);
let res;
return fetch(req.url, req)
.then(r => (res = r).json())
.then(data => {
res.data = data;
res.request = req;
client.emit('after', res);
if (res.ok) return data;
throw Object.assign(Error(res.statusText), {
data,
request: req
});
});
}
['get','post','put','patch', 'delete'].map(m => client[m] = (a,b,c)=>client.request(m.toUpperCase()+' '+a,b,c));
return client;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment