Skip to content
This repository has been archived by the owner on Sep 4, 2019. It is now read-only.

Commit

Permalink
Initial implementation of Feathers clients for jQuery, Superagent and…
Browse files Browse the repository at this point in the history
… Request.
  • Loading branch information
daffl committed Jun 1, 2015
1 parent dcdc75e commit fa5979f
Show file tree
Hide file tree
Showing 24 changed files with 850 additions and 182 deletions.
39 changes: 0 additions & 39 deletions Gruntfile.js

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 Feathers
Copyright (c) 2015 Feathers

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
95 changes: 95 additions & 0 deletions lib/arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
function noop() {}

function getCallback(args) {
var last = args[args.length - 1];
return typeof last === 'function' ? last : noop;
}

function getParams(args, position) {
var arg = args[position];
return typeof arg === 'object' ? arg : {};
}

function updateOrPatch(name) {
return function(args) {
var id = args[0];
var data = args[1];
var callback = getCallback(args);
var params = getParams(args, 2);

if(typeof id === 'function') {
throw new Error('First parameter for \'' + name + '\' can not be a function');
}

if(typeof data !== 'object') {
throw new Error('No data provided for \'' + name + '\'');
}

if(args.length > 4) {
throw new Error('Too many arguments for \'' + name + '\' service method');
}

return [ id, data, params, callback ];
};
}

function getOrRemove(name) {
return function(args) {
var id = args[0];
var params = getParams(args, 1);
var callback = getCallback(args);

if(args.length > 3) {
throw new Error('Too many arguments for \'' + name + '\' service method');
}

if(id === 'function') {
throw new Error('First parameter for \'' + name + '\' can not be a function');
}

return [ id, params, callback ];
};
}

var converters = {
find: function(args) {
var callback = getCallback(args);
var params = getParams(args, 0);

if(args.length > 2) {
throw new Error('Too many arguments for \'find\' service method');
}

return [ params, callback ];
},

create: function(args) {
var data = args[0];
var params = getParams(args, 1);
var callback = getCallback(args);

if(typeof data !== 'object') {
throw new Error('First parameter for \'create\' must be an object');
}

if(args.length > 3) {
throw new Error('Too many arguments for \'create\' service method');
}

return [ data, params, callback ];
},

update: updateOrPatch('update'),

patch: updateOrPatch('patch'),

get: getOrRemove('get'),

remove: getOrRemove('remove')
};

module.exports = function getArguments(method, args) {
return converters[method](args);
};

module.exports.noop = noop;
30 changes: 30 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var utils = require('./utils');

function app(base) {
if (typeof base !== 'string') {
base = '/';
}

return {
services: {},

base: base,

configure: function (cb) {
cb.call(this);
return this;
},

service: function (name) {
name = utils.stripSlashes(name);
if (!this.services[name]) {
this.services[name] = this.Service._create(name, this);
}
return this.services[name];
}
};
}

utils.extend(app, require('./rest'));

module.exports = app;
75 changes: 75 additions & 0 deletions lib/rest/base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
var query = require('querystring');
var Proto = require('uberproto');
var eventMixin = require('./events');
var utils = require('../utils');

module.exports = Proto.extend({
_create: Proto.create,

init: function(name, options) {
this.name = utils.stripSlashes(name);
this.options = utils.extend({}, options);
this.connection = options.connection;
this.base = options.base + '/' + name;
delete this.options.base;
},

makeUrl: function (params, id) {
var url = this.base;

if (typeof id !== 'undefined') {
url += '/' + id;
}

if(Object.keys(params).length !== 0) {
url += '?' + query.stringify(params);
}

return url;
},

find: function (params, callback) {
this.request({
url: this.makeUrl(params),
method: 'GET'
}, callback);
},

get: function(id, params, callback) {
this.request({
url: this.makeUrl(params, id),
method: 'GET'
}, callback);
},

create: function (data, params, callback) {
this.request({
url: this.makeUrl(params),
body: data,
method: 'POST'
}, callback);
},

update: function (id, data, params, callback) {
this.request({
url: this.makeUrl(params, id),
body: data,
method: 'PUT'
}, callback);
},

patch: function (id, data, params, callback) {
this.request({
url: this.makeUrl(params, id),
body: data,
method: 'PATCH'
}, callback);
},

remove: function (id, params, callback) {
this.request({
url: this.makeUrl(params, id),
method: 'DELETE'
}, callback);
}
}).mixin(eventMixin);
24 changes: 24 additions & 0 deletions lib/rest/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var EventEmitter = require('events').EventEmitter;
var utils = require('../utils');
var makeEmitting = function(name) {
return function() {
var callback = arguments[arguments.length - 1];
var _emit = this.emit.bind(this);
if(typeof callback === 'function') {
arguments[arguments.length - 1] = function(error, data) {
if(!error) {
_emit(name, data);
}
callback(error, data);
};
}
return this._super.apply(this, arguments);
}
};

module.exports = utils.extend({
create: makeEmitting('created'),
update: makeEmitting('updated'),
patch: makeEmitting('patched'),
remove: makeEmitting('removed')
}, EventEmitter.prototype);
5 changes: 5 additions & 0 deletions lib/rest/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
jquery: require('./jquery'),
request: require('./request'),
superagent: require('./superagent')
};
40 changes: 40 additions & 0 deletions lib/rest/jquery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
var utils = require('../utils');
var Base = require('./base');
var Service = Base.extend({
request: function (options, callback) {
var opts = utils.extend({
dataType: options.type || 'json'
}, options);

if(options.body) {
opts.data = JSON.stringify(options.body);
opts.contentType = 'application/json';
}

delete opts.type;
delete opts.body;

this.connection.ajax(opts).then(function (data) {
callback(null, data);
}, function (xhr) {
callback(new Error(xhr.responseText));
});
}
});

module.exports = function(jQuery) {
if(!jQuery && typeof window !== 'undefined') {
jQuery = window.jQuery;
}

if(typeof jQuery !== 'function') {
throw new Error('jQuery instance needs to be provided');
}

return function() {
this.Service = Service;
this.connection = jQuery;
}
};

module.exports.Service = Service;
28 changes: 28 additions & 0 deletions lib/rest/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var utils = require('../utils');
var Base = require('./base');
var Service = Base.extend({
request: function (options, callback) {
this.connection(utils.extend({
json: true
}, options), function(error, res, data) {
if(!error && res.statusCode >= 400) {
return callback(new Error(data));
}

callback(error, data);
});
}
});

module.exports = function(request) {
if(!request) {
throw new Error('request instance needs to be provided');
}

return function() {
this.Service = Service;
this.connection = request;
}
};

module.exports.Service = Service;
28 changes: 28 additions & 0 deletions lib/rest/superagent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var Base = require('./base');
var Service = Base.extend({
request: function (options, callback) {
var superagent = this.connection(options.method, options.url)
.type(options.type || 'json');

if(options.body) {
superagent.send(options.body);
}

superagent.end(function(error, res) {
callback(error, res && res.body);
});
}
});

module.exports = function(superagent) {
if(!superagent) {
throw new Error('Superagent needs to be provided');
}

return function() {
this.Service = Service;
this.connection = superagent;
}
};

module.exports.Service = Service;
Empty file added lib/sockets/primus.js
Empty file.
Loading

0 comments on commit fa5979f

Please sign in to comment.