Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

angular-sails

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-sails - npm Package Compare versions

Comparing version 1.1.4 to 2.0.0-beta.4

.jshintignore

8

bower.json
{
"name": "angular-sails",
"version": "1.1.4",
"version": "2.0.0-beta.4",
"authors": [

@@ -20,8 +20,8 @@ "Jan-Oliver Pantel <jan.pantel@gmail.com>",

"license": "MIT",
"homepage": "https://github.com/kyjan/angular-sails",
"homepage": "https://github.com/janpantel/angular-sails",
"dependencies": {
"angular": ">=1.2.*",
"sails.io.js": "*"
"socket.io-client": ">=1.3.0"
},
"devDependencies":{
"devDependencies": {
"angular-mocks": ">=1.2.*"

@@ -28,0 +28,0 @@ },

@@ -1,313 +0,742 @@

(function (angular, io) {
'use strict'/*global angular */
angular.module('ngSails', ['ng']);
/*!
* angular-sails
* An angular provider for using the sails socket.io api
* @version v2.0.0-beta.4
* @link https://github.com/janpantel/angular-sails
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
(function(window, angular, undefined){'use strict';
/*global angular, io */
(function(angular, io) {
'use strict';
if(io.sails){
io.sails.autoConnect = false;
angular.module('ngSails', ['ngSails.$sails']);
'use strict';
function parseHeaders(headers) {
var parsed = {},
key, val, i;
if (!headers) return parsed;
angular.forEach(headers.split('\n'), function(line) {
i = line.indexOf(':');
key = angular.lowercase(trim(line.substr(0, i)));
val = trim(line.substr(i + 1));
if (key) {
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
}
});
// copied from angular
function parseHeaders(headers) {
var parsed = {},
key, val, i;
if (!headers) return parsed;
angular.forEach(headers.split('\n'), function(line) {
i = line.indexOf(':');
key = lowercase(trim(line.substr(0, i)));
val = trim(line.substr(i + 1));
if (key) {
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
}
});
return parsed;
}
return parsed;
function executeHeaderFns(headers, config) {
var headerContent, processedHeaders = {};
angular.forEach(headers, function(headerFn, header) {
if (angular.isFunction(headerFn)) {
headerContent = headerFn(config);
if (headerContent != null) {
processedHeaders[header] = headerContent;
}
} else {
processedHeaders[header] = headerFn;
}
});
function trim(value) {
return angular.isString(value) ? value.trim() : value;
return processedHeaders;
}
function mergeHeaders(config, defHeaders) {
var reqHeaders = angular.extend({}, config.headers),
defHeaderName, lowercaseDefHeaderName, reqHeaderName;
defHeaders = angular.extend({}, defHeaders.common, defHeaders[angular.lowercase(config.method)]);
// using for-in instead of forEach to avoid unecessary iteration after header has been found
defaultHeadersIteration:
for (defHeaderName in defHeaders) {
lowercaseDefHeaderName = angular.lowercase(defHeaderName);
for (reqHeaderName in reqHeaders) {
if (angular.lowercase(reqHeaderName) === lowercaseDefHeaderName) {
continue defaultHeadersIteration;
}
}
function isPromiseLike (obj){
return obj && angular.isFunction(obj.then);
reqHeaders[defHeaderName] = defHeaders[defHeaderName];
}
// execute if header value is a function for merged headers
return executeHeaderFns(reqHeaders, shallowCopy(config));
}
function shallowCopy(src, dst) {
if (angular.isArray(src)) {
dst = dst || [];
for (var i = 0, ii = src.length; i < ii; i++) {
dst[i] = src[i];
}
} else if (angular.isObject(src)) {
dst = dst || {};
// copied from angular
function headersGetter(headers) {
var headersObj = angular.isObject(headers) ? headers : undefined;
return function(name) {
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
var value = headersObj[lowercase(name)];
if (value === void 0) {
value = null;
}
return value;
}
return headersObj;
for (var key in src) {
if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
dst[key] = src[key];
}
}
}
return dst || src;
}
function trim(value) {
return angular.isString(value) ? value.trim() : value;
}
function isPromiseLike(obj) {
return obj && angular.isFunction(obj.then);
}
// copied from angular
function headersGetter(headers) {
var headersObj = angular.isObject(headers) ? headers : undefined;
return function(name) {
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
var value = headersObj[angular.lowercase(name)];
if (value === void 0) {
value = null;
}
return value;
}
return headersObj;
};
}
function arrIndexOf(arr, val) {
if (!angular.isArray(arr)) {
throw new TypeError('Expected type "array" by got type "' + (Object.prototype.toString.call(arr)) + '".');
}
if (Array.prototype.indexOf) {
return arr.indexOf(val);
} else {
var i = 0;
var len = arr.length;
if (len === 0) {
return -1;
}
while (i < len) {
if (i in arr && arr[i] === val) {
return i;
}
i++;
}
return -1;
}
}
function buildUrl(url, params) {
if (!params) return url;
var parts = [];
forEachSorted(params, function(value, key) {
if (value === null || angular.isUndefined(value)) return;
if (!angular.isArray(value)) value = [value];
angular.forEach(value, function(v) {
if (angular.isObject(v)) {
if (angular.isDate(v)) {
v = v.toISOString();
} else {
v = angular.toJson(v);
}
}
parts.push(encodeUriQuery(key) + '=' +
encodeUriQuery(v));
});
});
if (parts.length > 0) {
url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
}
return url;
}
function forEachSorted(obj, iterator, context) {
var keys = sortedKeys(obj);
for (var i = 0; i < keys.length; i++) {
iterator.call(context, obj[keys[i]], keys[i]);
}
return keys;
}
function sortedKeys(obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys.sort();
}
function encodeUriQuery(val, pctEncodeSpaces) {
return encodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}
function isFile(obj) {
return Object.prototype.toString.call(obj) === '[object File]';
}
function isBlob(obj) {
return Object.prototype.toString.call(obj) === '[object Blob]';
}
var statusText = {
100: "100 Continue",
101: "101 Switching Protocols",
102: "102 Processing",
200: "200 OK",
201: "201 Created",
202: "202 Accepted",
203: "203 Non-Authoritative Information",
204: "204 No Content",
205: "205 Reset Content",
206: "206 Partial Content",
207: "207 Multi-Status",
208: "208 Already Reported",
226: "226 IM Used",
300: "300 Multiple Choices",
301: "301 Moved Permanently",
302: "302 Found",
303: "303 See Other",
304: "304 Not Modified",
305: "305 Use Proxy",
306: "306 (Unused)",
307: "307 Temporary Redirect",
308: "308 Permanent Redirect",
400: "400 Bad Request",
401: "401 Unauthorized",
402: "402 Payment Required",
403: "403 Forbidden",
404: "404 Not Found",
405: "405 Method Not Allowed",
406: "406 Not Acceptable",
407: "407 Proxy Authentication Required",
408: "408 Request Timeout",
409: "409 Conflict",
410: "410 Gone",
411: "411 Length Required",
412: "412 Precondition Failed",
413: "413 Payload Too Large",
414: "414 URI Too Long",
415: "415 Unsupported Media Type",
416: "416 Range Not Satisfiable",
417: "417 Expectation Failed",
422: "422 Unprocessable Entity",
423: "423 Locked",
424: "424 Failed Dependency",
426: "426 Upgrade Required",
428: "428 Precondition Required",
429: "429 Too Many Requests",
431: "431 Request Header Fields Too Large",
500: "500 Internal Server Error",
501: "501 Not Implemented",
502: "502 Bad Gateway",
503: "503 Service Unavailable",
504: "504 Gateway Timeout",
505: "505 HTTP Version Not Supported",
506: "506 Variant Also Negotiates",
507: "507 Insufficient Storage",
508: "508 Loop Detected",
510: "510 Not Extended",
511: "511 Network Authentication Required"
};
'use strict';
/* jshint newcap: false */
/* global headersGetter: true,
mergeHeaders: true,
arrIndexOf: true,
isFile: true,
isBlob: true
*/
angular.module('ngSails.$sails', ['ngSails.$sailsIo', 'ngSails.$sailsInterceptor'])
.provider('$sails', $sails);
function $sails($sailsInterceptorProvider, $sailsIoProvider) {
var provider = this;
var httpVerbsWithData = ['post', 'put', 'patch'];
provider.httpVerbs = $sailsIoProvider.httpVerbs = ['get', 'post', 'put', 'patch', 'delete', 'head'];
provider.eventNames = $sailsIoProvider.eventNames = ['on', 'off', 'once'];
provider.config = {
transports: ['websocket', 'polling']
};
provider.debug = $sailsInterceptorProvider.debug = $sailsIoProvider.debug = false;
provider.debugger = function(val) {
provider.debug = $sailsInterceptorProvider.debug = $sailsIoProvider.debug = val;
};
provider.defaults = {
transformResponse: [],
transformRequest: [],
headers: {} // TODO: what should the default default headers
};
provider.interceptors = $sailsInterceptorProvider.interceptors = [
/*function($injectables) {
return {
request: function(config) {},
response: function(response) {},
requestError: function(rejection) {},
responseError: function(rejection) {}
};
}*/
];
this.$get = ["$rootScope", "$q", "$log", "$timeout", "$sailsIo", "$sailsInterceptor", function($rootScope, $q, $log, $timeout, $sailsIo, $sailsInterceptor) {
var socket = new $sailsIo(provider.socket || provider.url, provider.config);
var socketFunctions = ['connect', 'disconnect', 'isConnected'];
function $sails(config) {
return $sails[config.method](config.url, config);
}
angular.module('ngSails').provider('$sails', function() {
var provider = this;
$sails._socket = socket;
this.httpVerbs = ['get', 'post', 'put', 'delete'];
function exposeSocketFunction(fnName) {
$sails[fnName] = socket[fnName].bind(socket);
}
this.eventNames = ['on', 'off'];
function exposeVerbEndpoints(methodName) {
this.url = undefined;
$sails[methodName] = function(url, data, requestConfig) {
var config = {
method: methodName,
transformRequest: provider.defaults.transformRequest,
transformResponse: provider.defaults.transformResponse
};
this.urlPrefix = '';
requestConfig = requestConfig || {};
this.config = {
transports: ['websocket', 'polling'],
useCORSRouteToGetCookie: false
// more compatible with $http method arguments
if (arrIndexOf(httpVerbsWithData, methodName) === -1) {
requestConfig = data || requestConfig;
delete requestConfig.data;
} else {
requestConfig.data = data;
}
config = angular.extend({}, config, requestConfig);
config.method = angular.uppercase(config.method || methodName);
config.headers = mergeHeaders(config, provider.defaults.headers);
config.url = (provider.urlPrefix || '') + (url || config.url);
if (angular.isUndefined(config.withCredentials) && !angular.isUndefined(provider.defaults.withCredentials)) {
config.withCredentials = provider.defaults.withCredentials;
}
var promise = $sailsInterceptor(socket[methodName].bind(socket), config);
promise.success = function(fn) {
promise.then(function(res) {
fn(res.data, res.status, headersGetter(res.headers), res.config);
});
return promise;
};
this.debug = false;
promise.error = function(fn) {
promise.then(null, function(res) {
fn(res.data, res.status, headersGetter(res.headers), res.config);
});
return promise;
};
// like https://docs.angularjs.org/api/ng/service/$http#interceptors
// but with sails.io arguments
var interceptorFactories = this.interceptors = [
/*function($injectables) {
return {
request: function(config) {},
response: function(response) {},
requestError: function(rejection) {},
responseError: function(rejection) {}
};
}*/
];
return promise;
/*@ngInject*/
this.$get = ["$q", "$injector", "$rootScope", "$log", "$timeout", function($q, $injector, $rootScope, $log, $timeout) {
var socket = (io.sails && io.sails.connect || io.connect)(provider.url, provider.config);
};
}
socket.connect = function(opts){
if(!socket.isConnected()){
var _opts = opts||{};
_opts = angular.extend({},provider.config,opts);
function exposeEventsEndpoitns(eventName) {
$sails[eventName] = socket[eventName].bind(socket);
}
// These are the options sails.io.js actually sets when making the connection.
socket.useCORSRouteToGetCookie = _opts.useCORSRouteToGetCookie;
socket.url = _opts.url || provider.url;
socket.multiplex = _opts.multiplex;
angular.forEach(provider.httpVerbs, exposeVerbEndpoints, this);
angular.forEach(provider.eventNames, exposeEventsEndpoitns, this);
angular.forEach(socketFunctions, exposeSocketFunction, this);
socket._connect();
}
return socket;
};
/**
* Update a model on sails pushes
* @param {String} name Sails model name
* @param {Array} models Array with model objects
* @returns {Function} Function to remove the model updater instance
*/
$sails.$modelUpdater = function(name, models) {
// TODO: separate out interceptors into its own file (and provider?).
// build interceptor chain
var reversedInterceptors = [];
angular.forEach(interceptorFactories, function(interceptorFactory) {
reversedInterceptors.unshift(
angular.isString(interceptorFactory) ?
$injector.get(interceptorFactory) : $injector.invoke(interceptorFactory)
);
});
var update = function(message) {
// Send the request using the socket
function serverRequest(config) {
var defer = $q.defer();
if (provider.debug) $log.info('$sails ' + config.method + ' ' + config.url, config.data || '');
$rootScope.$evalAsync(function() {
var i;
if (config.timeout > 0) {
$timeout(timeoutRequest, config.timeout);
} else if (isPromiseLike(config.timeout)) {
config.timeout.then(timeoutRequest);
}
switch (message.verb) {
socket['legacy_' + config.method.toLowerCase()](config.url, config.data, serverResponse);
case "created":
// create new model item
models.push(message.data);
break;
function timeoutRequest(){
serverResponse(null);
case "updated":
var obj;
for (i = 0; i < models.length; i++) {
if (models[i].id === message.id) {
obj = models[i];
break;
}
}
function serverResponse(result, jwr) {
// cant update if the angular-model does not have the item and the
// sails message does not give us the previous record
if (!obj && !message.previous) return;
if (!jwr) {
jwr = {
body: result,
headers: result.headers || {},
statusCode: result.statusCode || result.status || 0,
error: (function() {
if (this.statusCode < 200 || this.statusCode >= 400) {
return this.body || this.statusCode;
}
})()
};
}
if (!obj) {
// sails has given us the previous record, create it in our model
obj = message.previous;
models.push(obj);
}
jwr.data = jwr.body; // $http compat
jwr.status = jwr.statusCode; // $http compat
jwr.socket = socket;
jwr.url = config.url;
jwr.method = config.method;
jwr.config = config.config;
if (jwr.error) {
if (provider.debug) $log.warn('$sails response ' + jwr.statusCode + ' ' + config.url, jwr);
defer.reject(jwr);
} else {
if (provider.debug) $log.info('$sails response ' + config.url, jwr);
defer.resolve(jwr);
}
// update the model item
angular.extend(obj, message.data);
break;
case "destroyed":
for (i = 0; i < models.length; i++) {
if (models[i].id === message.id) {
models.splice(i, 1);
break;
}
}
break;
}
});
};
return defer.promise;
}
socket._socket.on(name, update);
function promisify(methodName) {
socket['legacy_' + methodName] = socket[methodName];
return function() {
socket._socket.off(name, update);
};
};
socket[methodName] = function(url, data, config) {
$sails.defaults = this.defaults;
var chain = [serverRequest, undefined];
return $sails;
}];
}
$sails.$inject = ["$sailsInterceptorProvider", "$sailsIoProvider"];
//TODO: more compatible with $http methods and config
'use strict';
var promise = $q.when({
url: provider.urlPrefix + url,
data: data,
socket: socket,
config: config || {},
method: methodName.toUpperCase()
});
/* global isPromiseLike: true,
headersGetter: true
*/
// apply interceptors
angular.forEach(reversedInterceptors, function(interceptor) {
if (interceptor.request || interceptor.requestError) {
chain.unshift(interceptor.request, interceptor.requestError);
}
if (interceptor.response || interceptor.responseError) {
chain.push(interceptor.response, interceptor.responseError);
}
});
angular.module('ngSails.$sailsInterceptor', [])
.provider('$sailsInterceptor', $sailsInterceptor);
while (chain.length) {
var thenFn = chain.shift();
var rejectFn = chain.shift();
function $sailsInterceptor() {
var provider = this;
provider.interceptors = [];
promise = promise.then(thenFn, rejectFn);
}
this.$get = ["$injector", "$q", function($injector, $q) {
// be $http compatible
promise.success = function(fn) {
promise.then(function(jwr) {
fn(jwr.body, jwr.statusCode, headersGetter(jwr.headers), jwr);
});
return promise;
};
promise.error = function(fn) {
promise.then(null, function(jwr) {
fn(jwr.body, jwr.statusCode, headersGetter(jwr.headers), jwr);
});
return promise;
};
var reversedInterceptors = [];
return promise;
};
}
angular.forEach(provider.interceptors, function(interceptorFactory) {
reversedInterceptors.unshift(angular.isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
});
function wrapEvent(eventName) {
if(socket[eventName] || socket._raw && socket._raw[eventName]) {
socket['legacy_' + eventName] = socket[eventName] || socket._raw[eventName];
socket[eventName] = function(event, cb) {
var wrapEventFn = null;
if (eventName == 'off') {
return socket['legacy_' + eventName](event, cb);
}else if (cb !== null && angular.isFunction(cb)) {
socket['legacy_' + eventName](event, wrapEventFn = function(result) {
$rootScope.$evalAsync(cb.bind(socket, result));
});
}
return wrapEventFn;
};
}
}
var intercept = function(sendRequest, config) {
var _sendRequest = sendRequest;
// sails.io.js doesn't have `once`, need to access it through `._raw`
socket.once = function(event, cb){
if (cb !== null && angular.isFunction(cb)) {
if(socket._raw){
socket._raw.once(event, function(result) {
$rootScope.$evalAsync(cb.bind(socket, result));
});
}
}
};
if (isPromiseLike(sendRequest)) {
_sendRequest = function() {
return sendRequest;
};
}
angular.forEach(provider.httpVerbs, promisify);
angular.forEach(provider.eventNames, wrapEvent);
var chain = [transformRequest, undefined, _sendRequest, undefined, transformResponse, transformResponse];
var promise = $q.when(config);
angular.forEach(reversedInterceptors, function(interceptor) {
if (interceptor.request || interceptor.requestError) {
chain.unshift(interceptor.request, interceptor.requestError);
}
if (interceptor.response || interceptor.responseError) {
chain.push(interceptor.response, interceptor.responseError);
}
});
/**
* Update a model on sails pushes
* @param {String} name Sails model name
* @param {Array} models Array with model objects
*/
socket.$modelUpdater = function(name, models) {
while (chain.length) {
var thenFn = chain.shift();
var rejectFn = chain.shift();
var update = function(message) {
promise = promise.then(thenFn, rejectFn);
}
$rootScope.$evalAsync(function(){
var i;
return promise;
};
switch (message.verb) {
function transformRequest(config) {
return angular.extend({}, config, {
data: transformData(config.data, headersGetter(config.headers), config.transformRequest || [])
});
}
case "created":
// create new model item
models.push(message.data);
break;
function transformResponse(response) {
var resp = angular.extend({}, response, {
data: transformData(response.data, response.headers, response.config && response.config.transformResponse || [])
});
return (200 <= response.status && response.status < 300) ? resp : $q.reject(resp);
}
case "updated":
var obj;
for (i = 0; i < models.length; i++) {
if (models[i].id === message.id) {
obj = models[i];
break;
}
}
function transformData(data, headers, fns) {
if (angular.isFunction(fns)){
return fns(data, headers);
}
// cant update if the angular-model does not have the item and the
// sails message does not give us the previous record
if (!obj && !message.previous) return;
angular.forEach(fns, function(fn) {
data = fn(data, headers);
});
if (!obj) {
// sails has given us the previous record, create it in our model
obj = message.previous;
models.push(obj);
}
return data;
}
// update the model item
angular.extend(obj, message.data);
break;
return intercept;
}];
}
case "destroyed":
for (i = 0; i < models.length; i++) {
if (models[i].id === message.id) {
models.splice(i, 1);
break;
}
}
break;
}
});
};
'use strict';
socket.legacy_on(name, update);
/* global statusText: true,
buildUrl: true
*/
return function(){
socket.legacy_off(name, update);
};
};
angular.module('ngSails.$sailsIo', ['ngSails.sailsSdk', 'ngSails.socketIo'])
.provider('$sailsIo', $sailsIo);
return socket;
}];
this.$get.$inject = ["$q", "$injector", "$rootScope", "$log", "$timeout"];
function $sailsIo() {
var provider = this;
provider.httpVerbs = ['get', 'post', 'put', 'delete'];
provider.eventNames = ['on', 'off', 'once'];
this.$get = ["$rootScope", "$q", "$log", "socketIo", "sailsSdk", function($rootScope, $q, $log, socketIo, sailsSdk) {
var io = socketIo;
function SailsIo(url, config) {
return this.connect(url, config);
}
SailsIo.prototype.connect = function(url, config) {
var self = this;
config = config || {};
if(self._socket && self._socket.connected){
throw new Error('Socket is already connected.');
}
if(!self.connectDefer){
self.connectDefer = $q.defer();
}
if (angular.isObject(url) && angular.isFunction(url.on) && angular.isFunction(url.emit)){
// user passed in a socket, lets use it.
self._socket = url;
self.connectDefer.resolve();
}else{
if(!angular.isString(config.query)){
config.query = sailsSdk.versionString();
}else{
config.query += '&'+sailsSdk.versionString();
}
if (!self._socket || !self._socket.connected) {
self._socket = io(url || config.url, config);
self.connectDefer.resolve();
}
}
if (provider.debug) {
self.on('connect', $log.info.bind(self, '$sails connected.'));
self.on('disconnect', $log.info.bind(self, '$sails disconnected.'));
self.on('reconnecting', function(attemps) {
$log.warn.bind(self, '$sails is attemping to reconnect. (#' + attemps + ')');
});
self.on('reconnect', function(transport, attemps) {
$log.info.bind(self, '$sails successfully reconnected after ' + attemps + ' attemps.');
});
self.on('error', function(err) {
$log.error('$sails could not connect:', err);
});
}
return self;
};
SailsIo.prototype.disconnect = function() {
var self = this;
if (self._socket) {
self._socket.disconnect();
}
if(self.connectDefer){
self.connectDefer.reject('disconnect');
}
self.connectDefer = $q.defer();
};
SailsIo.prototype.isConnected = function() {
if (!this._socket) {
return false;
}
return this._socket.connected;
};
SailsIo.prototype._send = function(req, res) {
var self = this;
var sailsEndpoint = angular.lowercase(req.method);
self.connectDefer.promise.then(function sendRequest() {
if (provider.debug) {
$log.info('$sails ' + req.method + ' ' + req.url, req.data || '');
}
self._socket.emit(sailsEndpoint, {data: req.data, headers: req.headers, url: req.url}, function requestResponse(response) {
if (provider.debug) {
$log.info('$sails' + req.method + ' ' + req.url + ' response received', response);
}
response = response || {};
var serverResponse = {
data: response.body || response,
status: response.statusCode || response.status || response.Status || 200,
headers: response.headers || {},
config: req
};
serverResponse.statusText = statusText[serverResponse.status];
if (200 <= serverResponse.status && serverResponse.status < 300) {
res.reject(serverResponse);
} else {
res.resolve(serverResponse);
}
});
}, function voidRequest() {
if (provider.debug) {
$log.warn('$sails' + req.method + ' ' + req.url + ' request terminated', req);
}
res.reject({
data: null,
status: 0,
headers: {},
config: req,
statusText: null
});
});
};
SailsIo.prototype._req = function(req) {
var self = this;
var res = $q.defer();
req.url = req.url.replace(/^(.+)\/*\s*$/, '$1');
req.headers = req.headers || {};
req.data = req.params || req.data || {};
req.method = angular.uppercase(req.method);
if (typeof req.url !== 'string') {
throw new Error('Invalid or missing URL!');
}
self._send(req, res);
return res.promise;
};
angular.forEach(provider.httpVerbs, function(method) {
SailsIo.prototype[method] = function(req){
req.method = req.method || method;
return SailsIo.prototype._req.apply(this, [req]);
};
});
}(angular, io));
}(angular, io));
angular.forEach(provider.eventNames, function(ev) {
SailsIo.prototype[ev] = function(evt, cb) {
var self = this;
if (cb !== null && angular.isFunction(cb)) {
self._socket[ev](evt, function(result) {
$rootScope.$evalAsync(cb.bind(self, result));
});
}
};
}, this);
return SailsIo;
}];
}
'use strict';
// Sailsjs expects this information in the request...
angular.module('ngSails.sailsSdk', [])
.constant('sailsSdk', {
info: {
version: {
key: '__sails_io_sdk_version',
value: '0.11.0'
},
platform: {
key: '__sails_io_sdk_platform',
value: typeof module === 'undefined' ? 'browser' : 'node'
},
language: {
key: '__sails_io_sdk_language',
value: 'javascript'
}
},
versionString: function() {
var self = this;
return (function(){
var tmp = [];
angular.forEach(self.info, function(data){
tmp.push(data.key+'='+data.value);
});
return tmp.join('&');
}());
}
});
'use strict';
angular.module('ngSails.socketIo', [])
.factory('socketIo', socketIo);
function socketIo($window) {
if (!$window.io) {
throw new Error('Socket.io-client not found. Ensure socket.io-client is loaded before this script');
}
return $window.io;
}
socketIo.$inject = ["$window"];
})(window, window.angular);

@@ -1,1 +0,8 @@

!function(e,t){"use strict";e.module("ngSails",["ng"]),function(e,t){function n(t){var n,r,s,i={};return t?(e.forEach(t.split("\n"),function(e){s=e.indexOf(":"),n=lowercase(o(e.substr(0,s))),r=o(e.substr(s+1)),n&&(i[n]=i[n]?i[n]+", "+r:r)}),i):i}function o(t){return e.isString(t)?t.trim():t}function r(t){return t&&e.isFunction(t.then)}function s(t){var o=e.isObject(t)?t:void 0;return function(e){if(o||(o=n(t)),e){var r=o[lowercase(e)];return void 0===r&&(r=null),r}return o}}t.sails&&(t.sails.autoConnect=!1),e.module("ngSails").provider("$sails",function(){var n=this;this.httpVerbs=["get","post","put","delete"],this.eventNames=["on","off"],this.url=void 0,this.urlPrefix="",this.config={transports:["websocket","polling"],useCORSRouteToGetCookie:!1},this.debug=!1;var o=this.interceptors=[];this.$get=["$q","$injector","$rootScope","$log","$timeout",function(i,u,a,c,f){function l(e){function t(){o(null)}function o(t,o){o||(o={body:t,headers:t.headers||{},statusCode:t.statusCode||t.status||0,error:function(){return this.statusCode<200||this.statusCode>=400?this.body||this.statusCode:void 0}()}),o.data=o.body,o.status=o.statusCode,o.socket=g,o.url=e.url,o.method=e.method,o.config=e.config,o.error?(n.debug&&c.warn("$sails response "+o.statusCode+" "+e.url,o),s.reject(o)):(n.debug&&c.info("$sails response "+e.url,o),s.resolve(o))}var s=i.defer();return n.debug&&c.info("$sails "+e.method+" "+e.url,e.data||""),e.timeout>0?f(t,e.timeout):r(e.timeout)&&e.timeout.then(t),g["legacy_"+e.method.toLowerCase()](e.url,e.data,o),s.promise}function d(t){g["legacy_"+t]=g[t],g[t]=function(o,r,u){var a=[l,void 0],c=i.when({url:n.urlPrefix+o,data:r,socket:g,config:u||{},method:t.toUpperCase()});for(e.forEach(v,function(e){(e.request||e.requestError)&&a.unshift(e.request,e.requestError),(e.response||e.responseError)&&a.push(e.response,e.responseError)});a.length;){var f=a.shift(),d=a.shift();c=c.then(f,d)}return c.success=function(e){return c.then(function(t){e(t.body,t.statusCode,s(t.headers),t)}),c},c.error=function(e){return c.then(null,function(t){e(t.body,t.statusCode,s(t.headers),t)}),c},c}}function h(t){(g[t]||g._raw&&g._raw[t])&&(g["legacy_"+t]=g[t]||g._raw[t],g[t]=function(n,o){var r=null;return"off"==t?g["legacy_"+t](n,o):(null!==o&&e.isFunction(o)&&g["legacy_"+t](n,r=function(e){a.$evalAsync(o.bind(g,e))}),r)})}var g=(t.sails&&t.sails.connect||t.connect)(n.url,n.config);g.connect=function(t){if(!g.isConnected()){var o=t||{};o=e.extend({},n.config,t),g.useCORSRouteToGetCookie=o.useCORSRouteToGetCookie,g.url=o.url||n.url,g.multiplex=o.multiplex,g._connect()}return g};var v=[];return e.forEach(o,function(t){v.unshift(e.isString(t)?u.get(t):u.invoke(t))}),g.once=function(t,n){null!==n&&e.isFunction(n)&&g._raw&&g._raw.once(t,function(e){a.$evalAsync(n.bind(g,e))})},e.forEach(n.httpVerbs,d),e.forEach(n.eventNames,h),g.$modelUpdater=function(t,n){var o=function(t){a.$evalAsync(function(){var o;switch(t.verb){case"created":n.push(t.data);break;case"updated":var r;for(o=0;o<n.length;o++)if(n[o].id===t.id){r=n[o];break}if(!r&&!t.previous)return;r||(r=t.previous,n.push(r)),e.extend(r,t.data);break;case"destroyed":for(o=0;o<n.length;o++)if(n[o].id===t.id){n.splice(o,1);break}}})};return g.legacy_on(t,o),function(){g.legacy_off(t,o)}},g}],this.$get.$inject=["$q","$injector","$rootScope","$log","$timeout"]})}(e,t)}(angular,io);
/*!
* angular-sails
* An angular provider for using the sails socket.io api
* @version v2.0.0-beta.4
* @link https://github.com/janpantel/angular-sails
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
!function(e,t,n){"use strict";function r(e){var n,r,o,s={};return e?(t.forEach(e.split("\n"),function(e){o=e.indexOf(":"),n=t.lowercase(a(e.substr(0,o))),r=a(e.substr(o+1)),n&&(s[n]=s[n]?s[n]+", "+r:r)}),s):s}function o(e,n){var r,o={};return t.forEach(e,function(e,s){t.isFunction(e)?(r=e(n),null!=r&&(o[s]=r)):o[s]=e}),o}function s(e,n){var r,s,a,c=t.extend({},e.headers);n=t.extend({},n.common,n[t.lowercase(e.method)]);e:for(r in n){s=t.lowercase(r);for(a in c)if(t.lowercase(a)===s)continue e;c[r]=n[r]}return o(c,i(e))}function i(e,n){if(t.isArray(e)){n=n||[];for(var r=0,o=e.length;o>r;r++)n[r]=e[r]}else if(t.isObject(e)){n=n||{};for(var s in e)("$"!==s.charAt(0)||"$"!==s.charAt(1))&&(n[s]=e[s])}return n||e}function a(e){return t.isString(e)?e.trim():e}function c(e){return e&&t.isFunction(e.then)}function u(e){var o=t.isObject(e)?e:n;return function(n){if(o||(o=r(e)),n){var s=o[t.lowercase(n)];return void 0===s&&(s=null),s}return o}}function d(e,n){if(!t.isArray(e))throw new TypeError('Expected type "array" by got type "'+Object.prototype.toString.call(e)+'".');if(Array.prototype.indexOf)return e.indexOf(n);var r=0,o=e.length;if(0===o)return-1;for(;o>r;){if(r in e&&e[r]===n)return r;r++}return-1}function f(e,n){var r=this,o=["post","put","patch"];r.httpVerbs=n.httpVerbs=["get","post","put","patch","delete","head"],r.eventNames=n.eventNames=["on","off","once"],r.config={transports:["websocket","polling"]},r.debug=e.debug=n.debug=!1,r["debugger"]=function(t){r.debug=e.debug=n.debug=t},r.defaults={transformResponse:[],transformRequest:[],headers:{}},r.interceptors=e.interceptors=[],this.$get=["$rootScope","$q","$log","$timeout","$sailsIo","$sailsInterceptor",function(e,n,i,a,c,f){function l(e){return l[e.method](e.url,e)}function h(e){l[e]=v[e].bind(v)}function p(e){l[e]=function(n,i,a){var c={method:e,transformRequest:r.defaults.transformRequest,transformResponse:r.defaults.transformResponse};a=a||{},-1===d(o,e)?(a=i||a,delete a.data):a.data=i,c=t.extend({},c,a),c.method=t.uppercase(c.method||e),c.headers=s(c,r.defaults.headers),c.url=(r.urlPrefix||"")+(n||c.url),t.isUndefined(c.withCredentials)&&!t.isUndefined(r.defaults.withCredentials)&&(c.withCredentials=r.defaults.withCredentials);var l=f(v[e].bind(v),c);return l.success=function(e){return l.then(function(t){e(t.data,t.status,u(t.headers),t.config)}),l},l.error=function(e){return l.then(null,function(t){e(t.data,t.status,u(t.headers),t.config)}),l},l}}function g(e){l[e]=v[e].bind(v)}var v=new c(r.socket||r.url,r.config),m=["connect","disconnect","isConnected"];return l._socket=v,t.forEach(r.httpVerbs,p,this),t.forEach(r.eventNames,g,this),t.forEach(m,h,this),l.$modelUpdater=function(n,r){var o=function(n){e.$evalAsync(function(){var e;switch(n.verb){case"created":r.push(n.data);break;case"updated":var o;for(e=0;e<r.length;e++)if(r[e].id===n.id){o=r[e];break}if(!o&&!n.previous)return;o||(o=n.previous,r.push(o)),t.extend(o,n.data);break;case"destroyed":for(e=0;e<r.length;e++)if(r[e].id===n.id){r.splice(e,1);break}}})};return v._socket.on(n,o),function(){v._socket.off(n,o)}},l.defaults=this.defaults,l}]}function l(){var e=this;e.interceptors=[],this.$get=["$injector","$q",function(r,o){function s(e){return t.extend({},e,{data:a(e.data,u(e.headers),e.transformRequest||[])})}function i(e){var n=t.extend({},e,{data:a(e.data,e.headers,e.config&&e.config.transformResponse||[])});return 200<=e.status&&e.status<300?n:o.reject(n)}function a(e,n,r){return t.isFunction(r)?r(e,n):(t.forEach(r,function(t){e=t(e,n)}),e)}var d=[];t.forEach(e.interceptors,function(e){d.unshift(t.isString(e)?r.get(e):r.invoke(e))});var f=function(e,r){var a=e;c(e)&&(a=function(){return e});var u=[s,n,a,n,i,i],f=o.when(r);for(t.forEach(d,function(e){(e.request||e.requestError)&&u.unshift(e.request,e.requestError),(e.response||e.responseError)&&u.push(e.response,e.responseError)});u.length;){var l=u.shift(),h=u.shift();f=f.then(l,h)}return f};return f}]}function h(){var e=this;e.httpVerbs=["get","post","put","delete"],e.eventNames=["on","off","once"],this.$get=["$rootScope","$q","$log","socketIo","sailsSdk",function(n,r,o,s,i){function a(e,t){return this.connect(e,t)}var c=s;return a.prototype.connect=function(n,s){var a=this;if(s=s||{},a._socket&&a._socket.connected)throw new Error("Socket is already connected.");return a.connectDefer||(a.connectDefer=r.defer()),t.isObject(n)&&t.isFunction(n.on)&&t.isFunction(n.emit)?(a._socket=n,a.connectDefer.resolve()):(t.isString(s.query)?s.query+="&"+i.versionString():s.query=i.versionString(),a._socket&&a._socket.connected||(a._socket=c(n||s.url,s),a.connectDefer.resolve())),e.debug&&(a.on("connect",o.info.bind(a,"$sails connected.")),a.on("disconnect",o.info.bind(a,"$sails disconnected.")),a.on("reconnecting",function(e){o.warn.bind(a,"$sails is attemping to reconnect. (#"+e+")")}),a.on("reconnect",function(e,t){o.info.bind(a,"$sails successfully reconnected after "+t+" attemps.")}),a.on("error",function(e){o.error("$sails could not connect:",e)})),a},a.prototype.disconnect=function(){var e=this;e._socket&&e._socket.disconnect(),e.connectDefer&&e.connectDefer.reject("disconnect"),e.connectDefer=r.defer()},a.prototype.isConnected=function(){return this._socket?this._socket.connected:!1},a.prototype._send=function(n,r){var s=this,i=t.lowercase(n.method);s.connectDefer.promise.then(function(){e.debug&&o.info("$sails "+n.method+" "+n.url,n.data||""),s._socket.emit(i,{data:n.data,headers:n.headers,url:n.url},function(t){e.debug&&o.info("$sails"+n.method+" "+n.url+" response received",t),t=t||{};var s={data:t.body||t,status:t.statusCode||t.status||t.Status||200,headers:t.headers||{},config:n};s.statusText=g[s.status],200<=s.status&&s.status<300?r.reject(s):r.resolve(s)})},function(){e.debug&&o.warn("$sails"+n.method+" "+n.url+" request terminated",n),r.reject({data:null,status:0,headers:{},config:n,statusText:null})})},a.prototype._req=function(e){var n=this,o=r.defer();if(e.url=e.url.replace(/^(.+)\/*\s*$/,"$1"),e.headers=e.headers||{},e.data=e.params||e.data||{},e.method=t.uppercase(e.method),"string"!=typeof e.url)throw new Error("Invalid or missing URL!");return n._send(e,o),o.promise},t.forEach(e.httpVerbs,function(e){a.prototype[e]=function(t){return t.method=t.method||e,a.prototype._req.apply(this,[t])}}),t.forEach(e.eventNames,function(e){a.prototype[e]=function(r,o){var s=this;null!==o&&t.isFunction(o)&&s._socket[e](r,function(e){n.$evalAsync(o.bind(s,e))})}},this),a}]}function p(e){if(!e.io)throw new Error("Socket.io-client not found. Ensure socket.io-client is loaded before this script");return e.io}t.module("ngSails",["ngSails.$sails"]);var g={100:"100 Continue",101:"101 Switching Protocols",102:"102 Processing",200:"200 OK",201:"201 Created",202:"202 Accepted",203:"203 Non-Authoritative Information",204:"204 No Content",205:"205 Reset Content",206:"206 Partial Content",207:"207 Multi-Status",208:"208 Already Reported",226:"226 IM Used",300:"300 Multiple Choices",301:"301 Moved Permanently",302:"302 Found",303:"303 See Other",304:"304 Not Modified",305:"305 Use Proxy",306:"306 (Unused)",307:"307 Temporary Redirect",308:"308 Permanent Redirect",400:"400 Bad Request",401:"401 Unauthorized",402:"402 Payment Required",403:"403 Forbidden",404:"404 Not Found",405:"405 Method Not Allowed",406:"406 Not Acceptable",407:"407 Proxy Authentication Required",408:"408 Request Timeout",409:"409 Conflict",410:"410 Gone",411:"411 Length Required",412:"412 Precondition Failed",413:"413 Payload Too Large",414:"414 URI Too Long",415:"415 Unsupported Media Type",416:"416 Range Not Satisfiable",417:"417 Expectation Failed",422:"422 Unprocessable Entity",423:"423 Locked",424:"424 Failed Dependency",426:"426 Upgrade Required",428:"428 Precondition Required",429:"429 Too Many Requests",431:"431 Request Header Fields Too Large",500:"500 Internal Server Error",501:"501 Not Implemented",502:"502 Bad Gateway",503:"503 Service Unavailable",504:"504 Gateway Timeout",505:"505 HTTP Version Not Supported",506:"506 Variant Also Negotiates",507:"507 Insufficient Storage",508:"508 Loop Detected",510:"510 Not Extended",511:"511 Network Authentication Required"};t.module("ngSails.$sails",["ngSails.$sailsIo","ngSails.$sailsInterceptor"]).provider("$sails",f),f.$inject=["$sailsInterceptorProvider","$sailsIoProvider"],t.module("ngSails.$sailsInterceptor",[]).provider("$sailsInterceptor",l),t.module("ngSails.$sailsIo",["ngSails.sailsSdk","ngSails.socketIo"]).provider("$sailsIo",h),t.module("ngSails.sailsSdk",[]).constant("sailsSdk",{info:{version:{key:"__sails_io_sdk_version",value:"0.11.0"},platform:{key:"__sails_io_sdk_platform",value:"undefined"==typeof module?"browser":"node"},language:{key:"__sails_io_sdk_language",value:"javascript"}},versionString:function(){var e=this;return function(){var n=[];return t.forEach(e.info,function(e){n.push(e.key+"="+e.value)}),n.join("&")}()}}),t.module("ngSails.socketIo",[]).factory("socketIo",p),p.$inject=["$window"]}(window,window.angular);

@@ -0,1 +1,3 @@

'use strict';
var pkg = require('./package.json');

@@ -10,4 +12,3 @@

'bower_components/angular-mocks/angular-mocks.js',
'mock/socket-io.js',
'bower_components/sails.io.js/sails.io.js'
'mock/socket-io.js'
],

@@ -33,3 +34,3 @@ 'karma-build': [

src: [
'src/**/*.js',
'src/**/*.js'
]

@@ -36,0 +37,0 @@ };

'use strict';
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
header = require('gulp-header'),
footer = require('gulp-footer'),
ngAnnotate = require('gulp-ng-annotate'),
gulpKarma = require('gulp-karma'),
pkg = require('./package.json'),
files = require('./files');
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var ngAnnotate = require('gulp-ng-annotate');
var uglify = require('gulp-uglifyjs');
var concat = require('gulp-concat');
var wrap = require('gulp-wrap');
var header = require('gulp-header');
var bump = require('gulp-bump');
var gulpKarma = require('gulp-karma');
var gulpSequence = require('gulp-sequence').use(gulp);
var pkg = require('./package.json');
var files = require('./files');
var karmaTestConfig = gulpKarma({configFile: 'karma.conf.js', action: 'run'});
var karmaTestConfig = gulpKarma({
configFile: 'karma.conf.js',
action: 'run'
});
var banner = '/*!\n' +
' * <%= pkg.name %>\n' +
' * <%= pkg.description %>\n' +
' * @version v<%= pkg.version %>\n' +
' * @link <%= pkg.homepage %>\n' +
' * @license MIT License, http://www.opensource.org/licenses/MIT\n' +
' */\n';
gulp.task('build-js', function () {
return gulp.src(files.mergeFilesFor('src'))
.pipe(ngAnnotate())
.pipe(concat(pkg.name+'.js'))
.pipe(header('(function (angular, io) {\n\'use strict\''))
.pipe(footer('}(angular, io));'))
.pipe(gulp.dest('./build/'))
.pipe(concat(pkg.name+'.min.js'))
.pipe(uglify())
.pipe(gulp.dest('./build/'));
gulp.task('bump', function() {
return gulp.src('./*.json')
.pipe(bump({
type: 'minor'
}))
.pipe(gulp.dest('./'));
});
gulp.task('dist-js', ['build-js'], function () {
return gulp.src('./build/*.js')
gulp.task('updatePkg', function(){
pkg = require('./package.json');
});
gulp.task('buildDev', function() {
return gulp.src(files.mergeFilesFor('src'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'))
.pipe(concat(pkg.name + '.js'))
.pipe(ngAnnotate())
.pipe(wrap('(function(window, angular, undefined){<%= contents %>})(window, window.angular);'))
.pipe(header(banner, {
pkg: pkg
}))
.pipe(gulp.dest('./build/'));
});
gulp.task('minBuild', function() {
return gulp.src('./build/' + pkg.name + '.js')
.pipe(uglify(pkg.name + '.min.js', {
outSourceMap: false,
mangle: true,
preserveComments: 'some'
}))
.pipe(header(banner, {
pkg: pkg
}))
.pipe(gulp.dest('./build/'));
});
gulp.task('copyBuild', function() {
return gulp.src('./build/*.js')
.pipe(gulp.dest('./dist/'));
});
gulp.task('test', function () {
return gulp.src(files.mergeFilesFor('karma-src')).pipe(karmaTestConfig);
gulp.task('default', function() {
return gulp.watch(files.mergeFilesFor('src'), ['test']);
});
gulp.task('test-build', ['build-js'], function () {
return gulp.src(files.mergeFilesFor('karma-build')).pipe(karmaTestConfig);
gulp.task('test', function() {
return gulp.src(files.mergeFilesFor('karma-src')).pipe(karmaTestConfig);
});
gulp.task('test-min', ['build-js'], function () {
return gulp.src(files.mergeFilesFor('karma-min')).pipe(karmaTestConfig);
gulp.task('testBuild', function() {
return gulp.src(files.mergeFilesFor('karma-build')).pipe(karmaTestConfig);
});
gulp.task('watch', function () {
return gulp.watch('src/**/*.js', ['build-js']);
gulp.task('testMin', function() {
return gulp.src(files.mergeFilesFor('karma-min')).pipe(karmaTestConfig);
});
gulp.task('default', ['build-js', 'watch']);
gulp.task('build', gulpSequence('buildDev', 'minBuild', ['testBuild', 'testMin']));
gulp.task('release', gulpSequence('bump', 'updatePkg', 'build', 'copyBuild'));
// Karma configuration
// Generated on Thu Jan 09 2014 13:59:16 GMT-0500 (EST)
'use strict';
module.exports = function (config) {

@@ -5,0 +5,0 @@ config.set({

@@ -0,28 +1,29 @@

'use strict';
// fix for phantomjs < 2.0
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
FNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof FNOP && oThis ? this : oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
FNOP.prototype = this.prototype;
fBound.prototype = new FNOP();
return fBound;
};
return fBound;
};
}
function io() {
var mockSocketObject = createMockSocketObject();
return mockSocketObject.connect();
var mockSocketObject = createMockSocketObject();
return mockSocketObject.connect();
}

@@ -32,61 +33,61 @@

var socket = {
on: function(ev, fn) {
(this._listeners[ev] = this._listeners[ev] || []).push(fn);
},
once: function(ev, fn) {
(this._listeners[ev] = this._listeners[ev] || []).push(fn);
fn._once = true;
},
emit: function(ev, data) {
if (this._listeners[ev]) {
var args = arguments;
this._listeners[ev].forEach(function(listener) {
if (listener._once) {
this.removeListener(ev, listener);
}
listener.apply(null, Array.prototype.slice.call(args, 1));
}.bind(this));
var socket = {
on: function(ev, fn) {
(this._listeners[ev] = this._listeners[ev] || []).push(fn);
},
once: function(ev, fn) {
(this._listeners[ev] = this._listeners[ev] || []).push(fn);
fn._once = true;
},
emit: function(ev, data) {
if (this._listeners[ev]) {
var args = arguments;
this._listeners[ev].forEach(function(listener) {
if (listener._once) {
this.removeListener(ev, listener);
}
listener.apply(null, Array.prototype.slice.call(args, 1));
}.bind(this));
}
},
_listeners: {},
removeListener: function(ev, fn) {
if (fn) {
var index = this._listeners[ev].indexOf(fn);
if (index > -1) {
this._listeners[ev].splice(index, 1);
}
} else {
delete this._listeners[ev];
}
},
off: function(ev, fn) {
if (fn) {
var index = this._listeners[ev].indexOf(fn);
if (index > -1) {
this._listeners[ev].splice(index, 1);
}
},
_listeners: {},
removeListener: function(ev, fn) {
if (fn) {
var index = this._listeners[ev].indexOf(fn);
if (index > -1) {
this._listeners[ev].splice(index, 1);
}
} else {
delete this._listeners[ev];
}
},
off: function(ev, fn) {
if (fn) {
var index = this._listeners[ev].indexOf(fn);
if (index > -1) {
this._listeners[ev].splice(index, 1);
}
} else {
delete this._listeners[ev];
}
},
removeAllListeners: function(ev) {
if (ev) {
delete this._listeners[ev];
} else {
this._listeners = {};
}
},
disconnect: function() {
this.connected = false;
this.emit('disconnect');
},
connect: function() {
this.connected = true;
this.emit('connect');
return this;
} else {
delete this._listeners[ev];
}
};
},
removeAllListeners: function(ev) {
if (ev) {
delete this._listeners[ev];
} else {
this._listeners = {};
}
},
disconnect: function() {
this.connected = false;
this.emit('disconnect');
},
connect: function() {
this.connected = true;
this.emit('connect');
return this;
}
};
return socket;
return socket;
}
{
"name": "angular-sails",
"version": "1.1.4",
"version": "2.0.0-beta.4",
"description": "An angular provider for using the sails socket.io api",
"scripts": {
"build": "gulp build-js",
"build": "gulp build",
"test": "gulp test"
},
"main": "index.js",
"main": "dist/angular-sails.js",
"repository": {
"type": "git",
"url": "https://github.com/janpantel/angular-sails.git"
"url": "https://github.com/kyjan/angular-sails.git"
},
"author": "Jan-Oliver Pantel <info@janpantel.de>",
"author": "Jan-Oliver Pantel <jan.pantel@gmail.com>",
"contributors": [
"Jan-Oliver Pantel <jan.pantel@gmail.com>",
"Evan Sharp <dumbdrum@gmail.com>"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/kyjan/angular-sails/issues"
"url": "https://github.com/janpantel/angular-sails/issues"
},
"homepage": "https://github.com/kyjan/angular-sails",
"dependencies": {
"angular": "^1.3.0",
"sails.io.js": "^0.11.0"
},
"homepage": "https://github.com/janpantel/angular-sails",
"devDependencies": {
"chai": "^1.10.0",
"gulp": "^3.5.6",
"gulp-bump": "^0.1.13",
"gulp-concat": "^2.2.0",
"gulp-footer": "^1.0.4",
"gulp-header": "^1.0.2",
"gulp-jshint": "^1.9.2",
"gulp-karma": "0.0.4",
"gulp-ng-annotate": "^0.3.3",
"gulp-uglify": "^0.2.1",
"gulp-sequence": "^0.3.2",
"gulp-uglifyjs": "^0.6.0",
"gulp-wrap": "^0.11.0",
"karma": "^0.12.21",

@@ -34,0 +37,0 @@ "karma-chai-sinon": "^0.1.4",

@@ -1,2 +0,2 @@

[![Build Status](https://travis-ci.org/janpantel/angular-sails.svg?branch=master)](https://travis-ci.org/janpantel/angular-sails)
[![Build Status](https://travis-ci.org/janpantel/angular-sails.svg?branch=2.0)](https://travis-ci.org/janpantel/angular-sails)

@@ -6,3 +6,3 @@ Angular Sails

This small module allows you to use Sails.JS's awesome socket.io api with AngularJS.
This module allows you to use Sails.JS's awesome socket.io api with AngularJS.

@@ -16,9 +16,12 @@ Just add a dependency to your module and controllers and get it going!

```
You must also include [sails.io.js](https://github.com/balderdashy/sails.io.js) in order to use this.
You must also include [sails.io-client](https://github.com/automattic/socket.io-client) in order to use this.
Switching from angular's `$http`?
---------------------------------
Angular Sails is a drop-in replacement for Angular's `$http` service. If you are currently using `$http` with sailsjs then switching to sockets is a snap, just replace `$http` with `$sails`!
Usage
-----
For a more complex example, have a look at the [tutorial by Maarten](https://github.com/maartendb/angular-sails-scrum-tutorial).
A small example:

@@ -40,6 +43,6 @@

$sails.get("/bars")
.success(function (data, status, headers, jwr) {
.success(function (data, status, headers, config) {
$scope.bars = data;
})
.error(function (data, status, headers, jwr) {
.error(function (data, status, headers, config) {
alert('Houston, we got a problem!');

@@ -57,3 +60,3 @@ });

// Watching for updates
var barsHandler = $sails.on("bars", function (message) {
$sails.on("bars", function (message) {
if (message.verb === "created") {

@@ -63,8 +66,2 @@ $scope.bars.push(message.data);

});
// Stop watching for updates
$scope.$on('$destroy', function() {
$sails.off('bars', barsHandler);
});
}());

@@ -78,5 +75,4 @@ });

### Sails.JS REST ###
Angular Sails wraps the native sails.js REST functions. For further information check out [the sails docs](http://sailsjs.org/#!documentation/sockets) and [Mike's Screencast](http://www.youtube.com/watch?v=GK-tFvpIR7c)
### Native socket functions ###
The sails service is nothing more like the native socket.io object!
Angular Sails mimics Angular's `$http` service to provide a drop-in socket replacement for http.
For more information check out [angular's `$http` docs](https://docs.angularjs.org/api/ng/service/$http#usage)<br />
<small>Note: Angular Sails does not have a `jsonp` method as jsonp is a specific implementation of HTTP</small>

@@ -1,2 +0,3 @@

/*global angular */
angular.module('ngSails', ['ng']);
'use strict';
angular.module('ngSails', ['ngSails.$sails']);

@@ -0,1 +1,3 @@

'use strict';
describe('Agnular Sails provider', function() {

@@ -7,3 +9,4 @@

requestErrorSpy,
responseErrorSpy;
responseErrorSpy,
socketRequestSpy,
methods = ['get', 'post', 'put', 'delete'],

@@ -23,7 +26,7 @@ response = {

spy = sinon.spy();
requestSpy = sinon.spy();
responseSpy = sinon.spy();
requestErrorSpy = sinon.spy();
responseErrorSpy = sinon.spy();
socketRequestSpy = sinon.spy();
requestSpy = sinon.spy().named('requestSpy');
responseSpy = sinon.spy().named('responseSpy');
requestErrorSpy = sinon.spy().named('requestErrorSpy');
responseErrorSpy = sinon.spy().named('responseErrorSpy');
socketRequestSpy = sinon.spy().named('socketRequestSpy');
});

@@ -43,2 +46,5 @@

mockIoSocket = io();
$sailsProvider.socket = mockIoSocket;
$sailsProvider.interceptors.push(function($q){

@@ -69,3 +75,2 @@ return {

$sails = _$sails_;
mockIoSocket = $sails._raw;

@@ -119,3 +124,3 @@ mockIoSocket.on('get', function(ctx, cb){

request: function(config){
return $q.reject('rejected');
return $q.reject(config);
}

@@ -127,3 +132,3 @@ };

inject(function($rootScope, $sails) {
$sails._raw.on('get', function(ctx, cb){
$sails._socket._socket.on('get', function(ctx, cb){
socketRequestSpy();

@@ -147,3 +152,3 @@ cb(response[ctx.url]);

response: function(config){
return $q.reject('rejected');
return $q.reject(config);
}

@@ -156,3 +161,3 @@ };

var errorSpy = sinon.spy();
$sails._raw.on('get', function(ctx, cb){
$sails._socket._socket.on('get', function(ctx, cb){
socketRequestSpy();

@@ -179,3 +184,3 @@ cb(response[ctx.url]);

expect(config.method).to.equal('POST');
expect(config.data).to.deep.equal({value: true})
expect(config.data).to.deep.equal({value: true});
spy();

@@ -190,3 +195,3 @@ return config;

var errorSpy = sinon.spy();
$sails._raw.on('post', function(ctx, cb){
$sails._socket._socket.on('post', function(ctx, cb){
socketRequestSpy();

@@ -196,3 +201,3 @@ cb(response[ctx.url]);

$sails.post('success',{value: true});
$sails.post('success', {value: true});
$rootScope.$digest();

@@ -222,4 +227,3 @@

var errorSpy = sinon.spy();
$sails._raw.on('post', function(ctx, cb){
expect(ctx.method).to.equal('post');
$sails._socket._socket.on('post', function(ctx, cb){
expect(ctx.url).to.equal('success');

@@ -231,3 +235,3 @@ expect(ctx.data).to.deep.equal({value: true});

$sails.get('error', {value: false});
$sails.get('error');
$rootScope.$digest();

@@ -277,3 +281,3 @@

inject(function($rootScope, $sails) {
$sails._raw.on('get', function(ctx, cb){
$sails._socket._socket.on('get', function(ctx, cb){
cb(response.success);

@@ -283,6 +287,6 @@ });

$sails.get('success').then(function(res){
expect(res.method).to.equal('GET');
expect(res.url).to.equal('successOuterInner');
expect(res.config.method).to.equal('GET');
expect(res.config.url).to.equal('successOuterInner');
expect(res.data).to.equal('{{Success!} inner} outer');
spy()
spy();
});

@@ -289,0 +293,0 @@ $rootScope.$digest();

@@ -0,1 +1,3 @@

'use strict';
describe('Agnular Sails service', function() {

@@ -24,3 +26,3 @@

$sails = _$sails_;
mockIoSocket = $sails._raw;
mockIoSocket = $sails._socket._socket;
spy = sinon.spy();

@@ -54,6 +56,6 @@ }));

it('should queue up requests', function () {
var getSpy = sinon.spy(),
postSpy = sinon.spy(),
getCbSpy = sinon.spy(),
postCbSpy = sinon.spy();
var getSpy = sinon.spy().named('getSpy'),
postSpy = sinon.spy().named('postSpy'),
getCbSpy = sinon.spy().named('getCbSpy'),
postCbSpy = sinon.spy().named('postCbSpy');

@@ -83,25 +85,19 @@ $sails.disconnect();

/* TODO: Someone determine how to test this
Because `$sails.connect()` automatically runs the queued calls on the new socket,
We cannot grab the other end of the new socket to watch for the calls and respond
to the calls.... This makes this really hard to test. In fact, from what I can
tell impossible to test.
*/
// mockIoSocket = $sails._raw;
//
// mockIoSocket.on('get', function(ctx, cb){
// getSpy();
// cb(response[ctx.url]);
// });
// mockIoSocket.on('post', function(ctx, cb){
// postSpy();
// cb(response[ctx.url]);
// });
//
// $scope.$digest();
//
// expect(getSpy).to.have.been.calledOnce;
// expect(postSpy).to.have.been.calledOnce;
// expect(getCbSpy).to.have.been.calledOnce;
// expect(postCbSpy).to.have.been.calledOnce;
mockIoSocket = $sails._socket._socket;
mockIoSocket.on('get', function(ctx, cb){
getSpy();
cb(response[ctx.url]);
});
mockIoSocket.on('post', function(ctx, cb){
postSpy();
cb(response[ctx.url]);
});
$scope.$digest();
expect(getSpy).to.have.been.calledOnce;
expect(postSpy).to.have.been.calledOnce;
expect(getCbSpy).to.have.been.calledOnce;
expect(postCbSpy).to.have.been.calledOnce;
});

@@ -123,94 +119,5 @@

});
it('should allow multiple listeners for the same event', function () {
var eventSpy = sinon.spy()
$sails.on('event', spy);
$sails.on('event', eventSpy);
mockIoSocket.emit('event');
$scope.$digest();
expect(spy).to.have.been.calledOnce;
expect(eventSpy).to.have.been.calledOnce;
});
it('should call the correct lisener', function () {
var eventSpy = sinon.spy()
$sails.on('event', spy);
$sails.on('anotherEvent', eventSpy);
mockIoSocket.emit('event');
$scope.$digest();
expect(spy).to.have.been.calledOnce;
expect(eventSpy).to.have.not.been.called;
});
});
describe('off', function() {
describe('by event name only', function(){
it('should remove all event listener by the given name', function () {
var eventSpy = sinon.spy()
$sails.on('event', spy);
$sails.on('event', eventSpy);
$sails.off('event');
mockIoSocket.emit('event');
$scope.$digest();
expect(spy).to.have.not.been.called;
expect(eventSpy).to.have.not.been.called;
});
it('should only the listeners that match the given event name', function () {
var eventSpy = sinon.spy()
var anotherEventSpy = sinon.spy()
$sails.on('event', spy);
$sails.on('event', eventSpy);
$sails.on('anotherEvent', anotherEventSpy);
$sails.off('event');
mockIoSocket.emit('event');
mockIoSocket.emit('anotherEvent');
$scope.$digest();
expect(spy).to.have.not.been.called;
expect(eventSpy).to.have.not.been.called;
expect(anotherEventSpy).to.have.been.calledOnce;
});
});
describe('by event name and function', function(){
it('should remove the listener with that function', function () {
var listener = $sails.on('event', spy);
$sails.off('event', listener);
mockIoSocket.emit('event');
$scope.$digest();
expect(spy).to.have.not.been.called;
});
it('should only remove the listener with the function', function () {
var eventSpy = sinon.spy()
var anotherEventSpy = sinon.spy()
$sails.on('event', spy);
var listner = $sails.on('event', eventSpy);
$sails.on('anotherEvent', anotherEventSpy);
$sails.off('event', listner);
mockIoSocket.emit('event');
mockIoSocket.emit('anotherEvent');
$scope.$digest();
expect(eventSpy).to.have.not.been.called;
expect(spy).to.have.been.calledOnce;
expect(anotherEventSpy).to.have.been.calledOnce;
});
});
});
describe('once', function () {

@@ -284,3 +191,3 @@

});
errorSpy = sinon.spy();
errorSpy = sinon.spy().named('errorSpy');
});

@@ -287,0 +194,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc