@ -1,2 +1,20 @@ |
|||||
# socketioMEANseed |
# socketioMEANseed |
||||
seed for a MEAN webapp with socketio, angular-material for the frontend |
seed for a MEAN webapp with socketio, angular-material for the frontend |
||||
|
|
||||
|
## seed project with |
||||
|
* MongoDB |
||||
|
* Expressjs |
||||
|
* Angularjs (with angular-material) |
||||
|
* Nodejs |
||||
|
* Socketio (angular-socket-io) |
||||
|
|
||||
|
## To init |
||||
|
on /server directory: |
||||
|
``` |
||||
|
npm start |
||||
|
``` |
||||
|
|
||||
|
on /www directory: |
||||
|
``` |
||||
|
npm start |
||||
|
``` |
@ -0,0 +1,109 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var jwt = require('jsonwebtoken'); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
app.set('superSecret', config.secret); |
||||
|
|
||||
|
/*******MODELS*********/ |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
var userModel = require('../models/userModel'); |
||||
|
var dietModel = require('../models/dietModel'); |
||||
|
var routineModel = require('../models/routineModel'); |
||||
|
|
||||
|
/** GET '/admin/users/' **/ |
||||
|
exports.getUsers = function (req, res) { |
||||
|
userModel.find() |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, users) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(users); |
||||
|
}); |
||||
|
}; |
||||
|
/** GET '/admin/users/:userid' **/ |
||||
|
exports.getUserById = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}) |
||||
|
.lean() |
||||
|
.populate('followers', 'name avatar') |
||||
|
.populate('following', 'name avatar') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'User not found.'}); |
||||
|
} else if (user) { |
||||
|
var nodes=[]; |
||||
|
var edges=[]; |
||||
|
var node={ |
||||
|
title: user.name, |
||||
|
label: user.name, |
||||
|
image: user.avatar, |
||||
|
shape: "image", |
||||
|
id: user._id |
||||
|
}; |
||||
|
nodes.push(node); |
||||
|
for(var i=0; i<user.followers.length; i++) |
||||
|
{ |
||||
|
var node={ |
||||
|
title: user.followers[i].name, |
||||
|
label: user.followers[i].name, |
||||
|
image: user.followers[i].avatar, |
||||
|
shape: "image", |
||||
|
id: user.followers[i]._id |
||||
|
}; |
||||
|
nodes.push(node); |
||||
|
var edge={ |
||||
|
from: user._id, |
||||
|
to: user.followers[i]._id, |
||||
|
arrows: { |
||||
|
from: user._id |
||||
|
}, |
||||
|
color: { |
||||
|
color: "#36bc9b" |
||||
|
} |
||||
|
}; |
||||
|
edges.push(edge); |
||||
|
} |
||||
|
|
||||
|
for(var i=0; i<user.following.length; i++) |
||||
|
{ |
||||
|
var indexJ=-1 |
||||
|
for(var j=0; j<nodes.length; j++) |
||||
|
{ |
||||
|
if(nodes[j].id.equals(user.following[i]._id)) |
||||
|
{ |
||||
|
indexJ=JSON.parse(JSON.stringify(j)); |
||||
|
} |
||||
|
} |
||||
|
if(indexJ==-1) |
||||
|
{//el node no estava als followers, afegim el node
|
||||
|
var node={ |
||||
|
title: user.following[i].name, |
||||
|
label: user.following[i].name, |
||||
|
image: user.following[i].avatar, |
||||
|
shape: "image", |
||||
|
id: user.following[i]._id |
||||
|
}; |
||||
|
nodes.push(node); |
||||
|
} |
||||
|
var edge={ |
||||
|
from: user._id, |
||||
|
to: user.following[i]._id, |
||||
|
arrows: { |
||||
|
to: user.following[i]._id |
||||
|
}, |
||||
|
color: { |
||||
|
color: "#4876b4" |
||||
|
} |
||||
|
}; |
||||
|
edges.push(edge); |
||||
|
} |
||||
|
|
||||
|
res.status(200).jsonp({ |
||||
|
nodes: nodes, |
||||
|
edges: edges |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,125 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var jwt = require('jsonwebtoken'); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
app.set('superSecret', config.secret); |
||||
|
|
||||
|
/*******MODELS*********/ |
||||
|
//var chefModel = require('../models/chefModel');
|
||||
|
var userModel = require('../models/userModel'); |
||||
|
var dietModel = require('../models/dietModel'); |
||||
|
|
||||
|
/**GET '/chefs' **/ |
||||
|
exports.getChefs = function (req, res) { |
||||
|
userModel.find({role: 'chef'}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, chefs) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(chefs); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/chefs/:chefid' **/ |
||||
|
exports.getChefById = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.chefid}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.exec(function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(chef); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** PUT '/chefs/:chefid' **/ |
||||
|
exports.updateChefById = function (req, res) { |
||||
|
var id = req.params.chefid; |
||||
|
var chef = req.body; |
||||
|
userModel.update({"_id": id}, chef, |
||||
|
function (err) { |
||||
|
if (err) return console.log(err); |
||||
|
console.log(chef); |
||||
|
res.status(200).jsonp(chef); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/chefs/:chefid' **/ |
||||
|
exports.deleteChefById = function (req, res) { |
||||
|
userModel.findByIdAndRemove({_id: req.params.chefid}, function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).send("Chef deleted"); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/chefs/register' **/ |
||||
|
exports.register = function (req, res) { |
||||
|
var chef = new userModel({ |
||||
|
name: req.body.name, |
||||
|
password: crypto.createHash('sha256').update(req.body.password).digest('base64'), |
||||
|
email: req.body.email, |
||||
|
role: req.body.role |
||||
|
}); |
||||
|
chef.save(function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(chef); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/chefs/login' **/ |
||||
|
exports.login = function (req, res) { |
||||
|
userModel.findOne({ |
||||
|
email: req.body.email |
||||
|
}) |
||||
|
.select('+password') |
||||
|
.exec(function (err, chef) { |
||||
|
if (err) throw err; |
||||
|
if (!chef) { |
||||
|
res.json({success: false, message: 'Authentication failed. chef not found.'}); |
||||
|
} else if (chef) { |
||||
|
req.body.password = crypto.createHash('sha256').update(req.body.password).digest('base64'); |
||||
|
if (chef.password != req.body.password) { |
||||
|
res.json({success: false, message: 'Authentication failed. Wrong password.'}); |
||||
|
} else { |
||||
|
var indexToken = -1; |
||||
|
for (var i = 0; i < chef.tokens.length; i++) { |
||||
|
if (chef.tokens[i].userAgent == req.body.userAgent) { |
||||
|
indexToken = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
console.log(indexToken); |
||||
|
if (indexToken == -1) {//userAgent no exist
|
||||
|
|
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
var newToken = { |
||||
|
userAgent: req.body.userAgent, |
||||
|
token: tokenGenerated |
||||
|
}; |
||||
|
chef.tokens.push(newToken); |
||||
|
} else {//userAgent already exist
|
||||
|
chef.tokens[indexToken].token = ""; |
||||
|
|
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
chef.tokens[indexToken].token = tokenGenerated; |
||||
|
} |
||||
|
chef.save(function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
// return the information including token as JSON
|
||||
|
chef.password = ""; |
||||
|
res.json({ |
||||
|
user: chef, |
||||
|
success: true, |
||||
|
message: 'Enjoy your token!', |
||||
|
token: tokenGenerated |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,42 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var config = require('../config/config'); |
||||
|
/*******MODELS*********/ |
||||
|
var contactModel = require('../models/contactModel'); |
||||
|
|
||||
|
/** GET '/contacts/' **/ |
||||
|
exports.getContacts = function (req, res) { |
||||
|
contactModel.find() |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, contacts) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(contacts); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/contacts/:contactsid' **/ |
||||
|
exports.getContactById = function (req, res) { |
||||
|
contactModel.findOne({_id: req.params.contactid}) |
||||
|
.exec(function (err, contact) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(contact); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**POST '/contact' **/ |
||||
|
exports.createContact = function (req, res) { |
||||
|
var contact = new contactModel({ |
||||
|
name: req.body.name, |
||||
|
subject: req.body.subject, |
||||
|
email: req.body.email, |
||||
|
description: req.body.description |
||||
|
}); |
||||
|
contact.save(function (err, contact) { |
||||
|
if (err) { |
||||
|
console.log(err.message); |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
res.status(200).jsonp(contact); |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,202 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var conversationModel = require('../models/conversationModel'); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
exports.getUserConversations = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.lean() |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'userA userB', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'messages.user', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.conversations); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**POST '/conversations' **/ |
||||
|
exports.createConversation = function (req, res) {//req.body.userB
|
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userA) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userA) { |
||||
|
res.json({success: false, message: 'userA not found.'}); |
||||
|
} else if (userA) { |
||||
|
//aquí ja hem agafat el userA a partir del seu token
|
||||
|
userModel.findOne({_id: req.body.userB}, function (err, userB) {//busquem l'userB
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userB) { |
||||
|
res.json({success: false, message: 'userB not found.'}); |
||||
|
} else if (userB) { |
||||
|
conversationModel.findOne({$or:[{userA: userA._id, userB: userB._id},{userA: userB._id, userB: userA._id}]}, function (err, conversation) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!conversation) { |
||||
|
console.log("conversation no exists, create new one"); |
||||
|
var conversation = new conversationModel({ |
||||
|
userA: userA._id, |
||||
|
userB: userB._id, |
||||
|
modifiedDate: Date() |
||||
|
}); |
||||
|
conversation.save(function (err, conversation) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
userA.conversations.push(conversation._id); |
||||
|
userA.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userB.conversations.push(conversation._id); |
||||
|
userB.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.lean() |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'userA userB', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'messages.user', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.conversations); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
} else if (conversation) { |
||||
|
console.log("conversation exists"); |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.lean() |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'userA userB', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'messages.user', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.conversations); |
||||
|
}); |
||||
|
} |
||||
|
});//end of conversation find
|
||||
|
|
||||
|
}//end else if (userB)
|
||||
|
});//end of userB find
|
||||
|
}//end else if (userA)
|
||||
|
});//end of userA find
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/**POST '/conversations/:conversationid' **/ |
||||
|
exports.addMessageToConversation = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userSender) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userSender) { |
||||
|
res.json({success: false, message: 'userSender not found.'}); |
||||
|
} else if (userSender) { |
||||
|
//aquí ja hem agafat el userSender a partir del seu token
|
||||
|
conversationModel.findOne({_id: req.params.conversationid}, function (err, conversation) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!conversation) { |
||||
|
res.json({success: false, message: 'conversation not found.'}); |
||||
|
} else if (conversation) { |
||||
|
var newmessage = { |
||||
|
user: userSender._id, |
||||
|
content: req.body.message, |
||||
|
date: Date() |
||||
|
}; |
||||
|
conversation.messages.push(newmessage); |
||||
|
conversation.modifiedDate=Date(); |
||||
|
|
||||
|
conversation.save(function (err, conversation) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//ara cal saber qui és l'userReciever (el que no ha enviat el missatge)
|
||||
|
var idUserReciever; |
||||
|
if(userSender._id.equals(conversation.userA)==false){ |
||||
|
idUserReciever=conversation.userA; |
||||
|
}else if(userSender._id.equals(conversation.userB)==false){ |
||||
|
idUserReciever=conversation.userB; |
||||
|
} |
||||
|
userModel.findOne({_id: idUserReciever}, function (err, userReciever) {//busquem l'userReciever
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userReciever) { |
||||
|
res.json({success: false, message: 'userReciever not found.'}); |
||||
|
} else if (userReciever) { |
||||
|
console.log("reciever: " + userReciever.name); |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: userSender.name + " sent a message to you", |
||||
|
link: "messages", |
||||
|
icon: "message.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
userReciever.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
userReciever.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.lean() |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'userA userB', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.populate({//això és per fer deep population
|
||||
|
path: 'conversations', |
||||
|
populate: { |
||||
|
path: 'messages.user', |
||||
|
model: 'userModel', |
||||
|
select: 'name avatar' |
||||
|
} |
||||
|
}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.conversations); |
||||
|
}); |
||||
|
}); |
||||
|
}//end else if (userReciever)
|
||||
|
});//end userReciever find
|
||||
|
}); |
||||
|
}//end else if (conversation)
|
||||
|
});//end of conversation find
|
||||
|
}//end else if (userSender)
|
||||
|
});//end of userSender find
|
||||
|
}; |
@ -0,0 +1,251 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
app.set('superSecret', config.secret); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
var dietModel = require('../models/dietModel'); |
||||
|
//var chefModel = require('../models/chefModel');
|
||||
|
|
||||
|
/** GET '/diets' ***/ |
||||
|
exports.getDiets = function (req, res) { |
||||
|
dietModel.find() |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, diets) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(diets); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/diets/:dietid' **/ |
||||
|
exports.getDietById = function (req, res) { |
||||
|
dietModel.findOne({_id: req.params.dietid}) |
||||
|
.lean() |
||||
|
.populate('chef', 'name avatar') |
||||
|
.exec(function (err, diet) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(diet); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**DELETE '/diets/:dietid' **/ |
||||
|
exports.deleteDietById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'chef'}, function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!chef) { |
||||
|
res.json({success: false, message: 'Chef not found.'}); |
||||
|
} else if (chef) { |
||||
|
for (var i = 0; i < chef.diets.length; i++) { |
||||
|
if (chef.diets[i].equals(req.params.dietid)) { |
||||
|
chef.diets.splice(i, 1); |
||||
|
chef.save(function (err, chef) {//guardem el chef amb la dieta treta
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
dietModel.findByIdAndRemove({_id: req.params.dietid}, function (err) { |
||||
|
if (err !== null) return res.send(500, err.message); |
||||
|
res.status(200).jsonp('Deleted diet'); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** PUT '/diets/:dietid' **/ |
||||
|
exports.updateDietById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'chef'}, function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!chef) { |
||||
|
res.json({success: false, message: 'Chef not found.'}); |
||||
|
} else if (chef) { |
||||
|
for (var i = 0; i < chef.diets.length; i++) { |
||||
|
if (chef.diets[i].equals(req.params.dietid)) { |
||||
|
chef.diets.splice(i, 1); //<-- splice? quan s'està fent un update? no s'hauria d'eliminar
|
||||
|
//tot i que no afecta, pq l'splice aquest després no es guarda a la base de dades pq no hi ha cap chef.save
|
||||
|
/* Solo si esa dieta ha sido creada por el chef */ |
||||
|
var id = req.params.dietid; |
||||
|
var diet = req.body; |
||||
|
dietModel.update({"_id": id}, diet, |
||||
|
function (err) { |
||||
|
if (err) return console.log(err); |
||||
|
console.log(diet); |
||||
|
res.status(200).jsonp(diet); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**POST '/diets' **/ |
||||
|
exports.createDiet = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'chef'}, function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!chef) { |
||||
|
res.json({success: false, message: 'Diet creation failed. Chef not found.'}); |
||||
|
} else if (chef) { |
||||
|
var diet = new dietModel({ |
||||
|
title: req.body.title, |
||||
|
description: req.body.description, |
||||
|
chef: chef._id,//a partir del token, pillem la id
|
||||
|
client: req.params.clientid//es guarda de quin user és la diet
|
||||
|
}); |
||||
|
//guardem la diet
|
||||
|
diet.save(function (err, diet) { |
||||
|
if (err) { |
||||
|
console.log(err.message); |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
//ara guardem la dietid al chef
|
||||
|
chef.diets.push(diet._id); |
||||
|
chef.save(function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
}); |
||||
|
res.status(200).jsonp(diet); |
||||
|
}); |
||||
|
}//else
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/diets/:dietid/days' **/ |
||||
|
exports.addDayToDiet = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'chef'}, function (err, chef) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!chef) { |
||||
|
res.json({success: false, message: 'Diet day addition failed. Trainer not found.'}); |
||||
|
} else if (chef) { |
||||
|
dietModel.findOne({_id: req.params.dietid}, function (err, diet) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
if (chef._id.equals(diet.chef)) {// si el chef que fa el post realment és el chef creator de la diet
|
||||
|
diet.days.push(req.body.day); |
||||
|
diet.save(function (err, diet) { |
||||
|
if (err) { |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
res.status(200).jsonp(diet); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}// end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/diets/choose' **/ |
||||
|
exports.chooseDiet = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'choosing diet failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
user.diets.push(req.params.dietid); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "choosing diet", |
||||
|
date: Date(), |
||||
|
value: +5 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 5; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(user); |
||||
|
}) |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/diets/choose' **/ |
||||
|
exports.unchooseDiet = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
for (var i = 0; i < user.diets.length; i++) { |
||||
|
if (user.diets[i].equals(req.params.dietid)) {//deletes the diets of the user with the dietid
|
||||
|
user.diets.splice(i, 1); |
||||
|
} |
||||
|
} |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "unchoosing diet", |
||||
|
date: Date(), |
||||
|
value: -7 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total - 7; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/diets/completeDay/:dietid' **/ |
||||
|
exports.completeDayGamificatedDiet = function (req, res) { |
||||
|
//1r intentamos darle los puntos al usuario por haber completado el día
|
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'choosing diet failed. user not found.'}); |
||||
|
} |
||||
|
else if (user) { |
||||
|
/* gamification */ |
||||
|
var reward = |
||||
|
{ |
||||
|
concept: "diet day complete", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
}); |
||||
|
//Ahora intentamos añadir done = true dentro del modelo dieta
|
||||
|
dietModel.findOne({'_id': req.params.dietid}, function (err, diet) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
if (!diet) { |
||||
|
res.json({success: false, message: 'Diet not found'}); |
||||
|
} |
||||
|
else if (diet) { |
||||
|
var indexDay = -1; |
||||
|
for (var i = 0; i < diet.days.length; i++) //diet.days
|
||||
|
{ |
||||
|
if (diet.days[i]._id.equals(req.body.dayid)) { |
||||
|
//aquí hem trobat el dia que busquem
|
||||
|
indexDay = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
}//End for looking for days
|
||||
|
if (indexDay > -1) { |
||||
|
/* True to day done*/ |
||||
|
diet.days[indexDay].done = true; |
||||
|
/* end of done*/ |
||||
|
diet.save(function (err) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
res.status(200).jsonp(diet); |
||||
|
});//diet.save
|
||||
|
}//End if when day foung
|
||||
|
else { |
||||
|
res.json({success: false, message: 'Day not found'}); |
||||
|
} |
||||
|
}//End else if found diet
|
||||
|
});//En dietModel for done = true
|
||||
|
}//End else if (user)
|
||||
|
});//En UserModel findOne()
|
||||
|
};//End function
|
@ -0,0 +1,269 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var publicationModel = require('../models/publicationModel'); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
/**GET '/publications' **/ |
||||
|
exports.getAllPublications = function (req, res) { |
||||
|
publicationModel.find() |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.lean() |
||||
|
.populate('user', 'name avatar') |
||||
|
.exec(function (err, publications) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publications) { |
||||
|
//
|
||||
|
} else if (publications) { |
||||
|
res.status(200).jsonp(publications); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
/** GET '/publications/getById/:publicationid' **/ |
||||
|
exports.getPublicationById = function (req, res) { |
||||
|
publicationModel.findOne({_id: req.params.publicationid}) |
||||
|
.lean() |
||||
|
.populate('likes', 'name avatar') |
||||
|
.exec(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publication) { |
||||
|
res.json({success: false, message: 'publication not found.'}); |
||||
|
} else if (publication) { |
||||
|
res.status(200).jsonp(publication); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
/**POST '/publications' **/ |
||||
|
exports.postPublication = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
//aquí ja hem agafat el user a partir del seu token
|
||||
|
var publication = new publicationModel({ |
||||
|
title: req.body.title, |
||||
|
content: req.body.content, |
||||
|
date: new Date(), |
||||
|
user: user._id, |
||||
|
photo: req.body.photo |
||||
|
}); |
||||
|
//fins aquí tenim la variable publication amb els continguts
|
||||
|
//ara cal 1r guardar el model publication a la base de dades
|
||||
|
publication.save(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//i 2n, afegir la id de la publicació generada al user.publications
|
||||
|
user.publications.push(publication._id); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "added new publication to Timeline", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**GET '/users/:userid/publications' **/ |
||||
|
exports.getUserPublicationsByUserId = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
}).populate('publications') |
||||
|
.exec(function (error, user) { |
||||
|
if (error !== null) res.send(500, error.message); |
||||
|
console.log(JSON.stringify(user, null, "\t")); |
||||
|
res.status(200).jsonp(user.publications); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**DELETE '/publications/:publicationid' **/ |
||||
|
exports.deletePublicationById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
for (var i = 0; i < user.publications.length; i++) { |
||||
|
if (user.publications[i].equals(req.params.publicationid)) {//només si el user és qui ha fet la publication la pot esborrar
|
||||
|
user.publications.splice(i, 1); |
||||
|
user.save(function (err, user) {//guardem l'user
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
publicationModel.findByIdAndRemove({_id: req.params.publicationid}, function (err) { |
||||
|
if (err !== null) return res.send(500, err.message); |
||||
|
res.status(200).jsonp('Deleted'); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/publications/:publicationid/like' **/ |
||||
|
exports.likePublication = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log(user.name); |
||||
|
//ara busquem el userB
|
||||
|
publicationModel.findOne({_id: req.params.publicationid}, function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publication) { |
||||
|
res.json({success: false, message: 'publication not found.'}); |
||||
|
} else if (publication) { |
||||
|
|
||||
|
// for(var i=0; i<userB.timeline)
|
||||
|
publication.likes.push(user._id); |
||||
|
publication.save(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "liked publication " + publication.title, |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
//ara busquem el user que ha fet la publication que ha rebut el like
|
||||
|
userModel.findOne({_id: publication.user}) |
||||
|
.exec(function (err, userB) { |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "user clicked like", |
||||
|
link: "user/"+userB._id, |
||||
|
icon: "newlike.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
userB.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
userB.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
publicationModel.findOne({_id: req.params.publicationid}) |
||||
|
.lean() |
||||
|
.populate('user', 'name avatar') |
||||
|
.exec(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publication) { |
||||
|
//
|
||||
|
} else if (publication) { |
||||
|
res.status(200).jsonp(publication); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/publications/:publicationid/dislike' **/ |
||||
|
exports.dislikePublication = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log(user.name); |
||||
|
//ara busquem el userB
|
||||
|
publicationModel.findOne({_id: req.params.publicationid}, function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publication) { |
||||
|
res.json({success: false, message: 'publication not found.'}); |
||||
|
} else if (publication) { |
||||
|
|
||||
|
for (var i = 0; i < publication.likes.length; i++) { |
||||
|
if (publication.likes[i].equals(user._id)) { |
||||
|
publication.likes.splice(i, 1); |
||||
|
} |
||||
|
} |
||||
|
publication.save(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "disliked publication " + publication.title, |
||||
|
date: Date(), |
||||
|
value: -1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total - 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
publicationModel.findOne({_id: req.params.publicationid}) |
||||
|
.lean() |
||||
|
.populate('user', 'name avatar') |
||||
|
.exec(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publication) { |
||||
|
//
|
||||
|
} else if (publication) { |
||||
|
res.status(200).jsonp(publication); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/publications/newsfeed' **/ |
||||
|
var ObjectId = require('mongodb').ObjectID; |
||||
|
exports.getNewsFeed = function (req, res) {//getPublicationsFromFollowingUsers
|
||||
|
//primer agafem l'user que fa la petició, per saber quins users està seguint
|
||||
|
var newsfeed = []; |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'getting newsfeed failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log("getting newsfeed for user: " + user.name); |
||||
|
|
||||
|
var following = []; |
||||
|
for (var i = 0; i < user.following.length; i++) {//això ho fem perquè necessitem la array amb el contingut en format objectid
|
||||
|
following.push(new ObjectId(user.following[i])); |
||||
|
} |
||||
|
following.push(new ObjectId(user._id));//així també reb les seves pròpies publicacions
|
||||
|
|
||||
|
publicationModel.find({user: {$in: following}}) |
||||
|
.lean() |
||||
|
.populate('user', 'name avatar') |
||||
|
.exec(function (err, publications) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!publications) { |
||||
|
//
|
||||
|
} else if (publications) { |
||||
|
res.status(200).jsonp(publications); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,303 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
app.set('superSecret', config.secret); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
var routineModel = require('../models/routineModel'); |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
|
||||
|
/** GET '/routines/' **/ |
||||
|
exports.getRoutines = function (req, res) { |
||||
|
routineModel.find() |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, routines) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(routines); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/routines/:routineid' **/ |
||||
|
exports.getRoutineById = function (req, res) { |
||||
|
routineModel.findOne({_id: req.params.routineid}) |
||||
|
.lean() |
||||
|
.populate('trainer', 'name avatar') |
||||
|
.populate('client', 'name avatar points.total') |
||||
|
.exec(function (err, routine) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(routine); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/routines/:routineid' **/ |
||||
|
exports.deleteRoutineById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'trainer'}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'Trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
for (var i = 0; i < trainer.routines.length; i++) { |
||||
|
if (trainer.routines[i].equals(req.params.routineid)) {//Solo si esa routine ha sido creada por el trainer
|
||||
|
trainer.routines.splice(i, 1); |
||||
|
//també s'hauria de treure la referència al user que és client d'aquesta routine
|
||||
|
trainer.save(function (err, trainer) {//guardem el trainer amb la rutina treta
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
routineModel.findByIdAndRemove({_id: req.params.routineid}, function (err) {//elminem la routine
|
||||
|
if (err !== null) return res.send(500, err.message); |
||||
|
res.status(200).jsonp('Deleted routine'); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** PUT '/routines/:routineid' **/ |
||||
|
exports.updateRoutineById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role:'trainer'}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'Trainer not found.'}); |
||||
|
} else if (user) { |
||||
|
for (var i = 0; i < user.routines.length; i++) { |
||||
|
if (user.routines[i].equals(req.params.routineid)) { |
||||
|
user.routines.splice(i, 1);// <-- perquè es fa l'splice de user.routines si després no es guarda el user??
|
||||
|
/* Solo si esa routine ha sido creada por el trainer */ |
||||
|
var id = req.params.routineid; |
||||
|
var routine = req.body; |
||||
|
routineModel.update({"_id": id}, routine, |
||||
|
function (err) { |
||||
|
if (err) return console.log(err); |
||||
|
console.log(routine); |
||||
|
res.status(200).jsonp(routine); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/routines/addToClient/:clientid' **/ |
||||
|
exports.addRoutineToClient = function (req, res) { |
||||
|
userModel.findOne({ |
||||
|
'tokens.token': req.headers['x-access-token'], |
||||
|
'clients.client': req.params.clientid, |
||||
|
'role': 'trainer' |
||||
|
}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'Routine creation failed. Trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
var routine = new routineModel({ |
||||
|
title: req.body.title, |
||||
|
description: req.body.description, |
||||
|
trainer: trainer._id,//a partir del token, pillem la id
|
||||
|
client: req.params.clientid//es guarda de quin user és la routine
|
||||
|
}); |
||||
|
//guardem la routine
|
||||
|
routine.save(function (err, routine) { |
||||
|
if (err) { |
||||
|
console.log(err.message); |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
//ara guardem la routineid al trainer
|
||||
|
trainer.routines.push(routine._id); |
||||
|
trainer.save(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
}); |
||||
|
//res.status(200).jsonp(routine);
|
||||
|
//ara afegim la routine al client
|
||||
|
userModel.findOne({'_id': req.params.clientid}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'adding routine to client failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
user.routines.push(routine._id); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "new routine", |
||||
|
date: Date(), |
||||
|
value: +5 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 5; |
||||
|
/* end of gamification */ |
||||
|
|
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "trainer has added a routine to you", |
||||
|
link: "training", |
||||
|
icon: "newroutine.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
user.notifications.push(notification); |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(routine); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}); |
||||
|
}//else
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/routines/:routineid/days' **/ |
||||
|
exports.addDayToRoutine = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'Routine day addition failed. Trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
routineModel.findOne({_id: req.params.routineid}, function (err, routine) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
if (trainer._id.equals(routine.trainer)) {// si el trainer que fa el post realment és el trainer creator de la routine
|
||||
|
routine.days.push(req.body.day); |
||||
|
routine.save(function (err, routine) { |
||||
|
if (err) { |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
routineModel.findOne({_id: routine._id}) |
||||
|
.lean() |
||||
|
.populate('trainer', 'name avatar') |
||||
|
.populate('client', 'name avatar points.total') |
||||
|
.exec(function (err, routine) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(routine); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}// end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/routines/choose' **/ |
||||
|
exports.chooseRoutine = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'choosing routine failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log(user);//aquí potser caldria comprovar que la routine és la que han creat per l'user
|
||||
|
user.routines.push(req.body.routineid); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "choosing routine", |
||||
|
date: Date(), |
||||
|
value: +5 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 5; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/routines/choose' **/ |
||||
|
exports.unchooseRoutine = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'choosing routine failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
for (var i = 0; i < user.routines.length; i++) { |
||||
|
if (user.routines[i] == req.body.routineid) {//deletes the diets of the user with the dietid
|
||||
|
user.routines.splice(i, 1); |
||||
|
} |
||||
|
} |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "unchoosing routine", |
||||
|
date: Date(), |
||||
|
value: -7 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total - 7; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/routines/completeDay/:routineid' **/ |
||||
|
exports.completeDayGamificatedRoutine = function (req, res) { |
||||
|
//1r intentamos darle los puntos al usuario por haber completado el día
|
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'choosing routine failed. user not found.'}); |
||||
|
} |
||||
|
else if (user) { |
||||
|
/* gamification */ |
||||
|
var reward = |
||||
|
{ |
||||
|
concept: "routine day complete", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
}); |
||||
|
//Ahora intentamos añadir done = true dentro del modelo rutina
|
||||
|
routineModel.findOne({'_id': req.params.routineid}, function (err, routine) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
if (!routine) { |
||||
|
res.json({success: false, message: 'Routine not found'}); |
||||
|
} |
||||
|
else if (routine) { |
||||
|
var indexDay = -1; |
||||
|
for (var i = 0; i < routine.days.length; i++) //routine.days
|
||||
|
{ |
||||
|
if (routine.days[i]._id.equals(req.body.dayid)) { |
||||
|
//aquí hem trobat el dia que busquem
|
||||
|
indexDay = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
}//End for looking for days
|
||||
|
if (indexDay > -1) { |
||||
|
/* True to day done*/ |
||||
|
routine.days[indexDay].done = true; |
||||
|
/* end of done*/ |
||||
|
routine.save(function (err) { |
||||
|
if (err) |
||||
|
return res.send(500, err.message); |
||||
|
routineModel.findOne({_id: routine._id}) |
||||
|
.lean() |
||||
|
.populate('trainer', 'name avatar') |
||||
|
.populate('client', 'name avatar points.total') |
||||
|
.exec(function (err, routine) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(routine); |
||||
|
}); |
||||
|
});//Routine.save
|
||||
|
}//End if when day foung
|
||||
|
else { |
||||
|
res.json({success: false, message: 'Day not found'}); |
||||
|
} |
||||
|
}//End else if found routine
|
||||
|
});//En routineModel for done = true
|
||||
|
}//End else if (user)
|
||||
|
});//En UserModel findOne()
|
||||
|
};//End function
|
@ -0,0 +1,107 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var runModel = require('../models/runModel'); |
||||
|
var publicationModel = require('../models/publicationModel'); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
|
||||
|
/**POST '/publications' **/ |
||||
|
exports.postRun = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
//aquí ja hem agafat el user a partir del seu token
|
||||
|
var run = new runModel(req.body.newRun); |
||||
|
run.user=user._id; |
||||
|
//fins aquí tenim la variable publication amb els continguts
|
||||
|
//ara cal 1r guardar el model publication a la base de dades
|
||||
|
run.save(function (err, run) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//i 2n, afegir la id de la publicació generada al user.publications
|
||||
|
user.runs.push(run._id); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "added new run to user", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//res.status(200).jsonp(user);
|
||||
|
//ara farem una publicació ensenyant que ha fet aquest run
|
||||
|
var publication = new publicationModel({ |
||||
|
title: "new run '" + run.title + "'!", |
||||
|
content: "distance of: " + run.distance + ". View my runs at my profile", |
||||
|
date: new Date(), |
||||
|
user: user._id, |
||||
|
photo: run.photo |
||||
|
}); |
||||
|
//fins aquí tenim la variable publication amb els continguts
|
||||
|
//ara cal 1r guardar el model publication a la base de dades
|
||||
|
publication.save(function (err, publication) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//i 2n, afegir la id de la publicació generada al user.publications
|
||||
|
user.publications.push(publication._id); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "added new publication to Timeline", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
|
||||
|
if(!user.totalkm) |
||||
|
{ |
||||
|
user.totalkm=0; |
||||
|
} |
||||
|
user.totalkm=user.totalkm + run.distance; |
||||
|
|
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**GET '/users/:userid/publications' **/ |
||||
|
exports.getRunsByUserId = function (req, res) { |
||||
|
userModel.findOne({ |
||||
|
_id: req.params.userid |
||||
|
}) |
||||
|
.populate('runs') |
||||
|
.exec(function (error, user) { |
||||
|
if (error !== null) res.send(500, error.message); |
||||
|
|
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}; |
||||
|
/** GET '/run/getById/:publicationid' **/ |
||||
|
exports.getRunByRunId = function (req, res) { |
||||
|
runModel.findOne({_id: req.params.runid}) |
||||
|
.lean() |
||||
|
.populate('user', 'name avatar') |
||||
|
.exec(function (err, run) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!run) { |
||||
|
res.json({success: false, message: 'run not found.'}); |
||||
|
} else if (run) { |
||||
|
res.status(200).jsonp(run); |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,433 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var jwt = require('jsonwebtoken'); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
app.set('superSecret', config.secret); |
||||
|
|
||||
|
/*******MODELS*********/ |
||||
|
//var trainerModel = require('../models/trainerModel');
|
||||
|
var userModel = require('../models/userModel'); |
||||
|
var dietModel = require('../models/dietModel'); |
||||
|
var routineModel = require('../models/routineModel'); |
||||
|
|
||||
|
/** GET '/trainers' **/ |
||||
|
exports.getTrainers = function (req, res) { |
||||
|
userModel.find({role: 'trainer'}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainers); |
||||
|
}); |
||||
|
}; |
||||
|
exports.getTrainersByDisciplinesArray = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'sending petition failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
if(user.disciplines[0]) |
||||
|
{ |
||||
|
userModel.find({ |
||||
|
role: 'trainer', |
||||
|
$and: [ |
||||
|
{_id: { $nin: user._id}}, |
||||
|
{_id: { $nin: user.trainers}} |
||||
|
], |
||||
|
'disciplines.name': user.disciplines[0].name//per ara torna els trainers que tinguin la discipline[0] del user client
|
||||
|
}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainers); |
||||
|
}); |
||||
|
}else{ |
||||
|
userModel.find({ |
||||
|
role: 'trainer', |
||||
|
$and: [ |
||||
|
{_id: { $nin: user._id}}, |
||||
|
{_id: { $nin: user.trainers}} |
||||
|
] |
||||
|
}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainers); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/trainers/:trainerid' **/ |
||||
|
exports.getTrainerById = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.trainerid, role: 'trainer'}) |
||||
|
.lean() |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('clients.client', 'name avatar points') |
||||
|
.populate('clientsPetitions.clientid', 'name avatar') |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/trainers/searchByDiscipline' **/ |
||||
|
exports.searchByDiscipline = function (req, res) { |
||||
|
userModel.find({'disciplines.name': req.params.discipline, role: 'trainer'}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainers); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/trainers/register' **/ |
||||
|
exports.register = function (req, res) { |
||||
|
var trainer = new userModel({ |
||||
|
name: req.body.name, |
||||
|
password: crypto.createHash('sha256').update(req.body.password).digest('base64'), |
||||
|
email: req.body.email, |
||||
|
avatar: 'img/user.png', |
||||
|
background: 'img/background.png', |
||||
|
role: req.body.role, |
||||
|
discipline: req.body.discipline, |
||||
|
points: { |
||||
|
total: 0 |
||||
|
} |
||||
|
}); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "account created", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
trainer.points.history.push(reward); |
||||
|
trainer.points.total = trainer.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
trainer.save(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/trainers/login' **/ |
||||
|
exports.login = function (req, res) { |
||||
|
userModel.findOne({ |
||||
|
email: req.body.email, role: 'trainer' |
||||
|
}) |
||||
|
.select('+password') |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) throw err; |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'Authentication failed. trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
req.body.password = crypto.createHash('sha256').update(req.body.password).digest('base64'); |
||||
|
if (trainer.password != req.body.password) { |
||||
|
res.json({success: false, message: 'Authentication failed. Wrong password.'}); |
||||
|
} else { |
||||
|
var indexToken = -1; |
||||
|
for (var i = 0; i < trainer.tokens.length; i++) { |
||||
|
if (trainer.tokens[i].userAgent == req.body.userAgent) { |
||||
|
indexToken = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
console.log(indexToken); |
||||
|
if (indexToken == -1) {//userAgent no exist
|
||||
|
|
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
var newToken = { |
||||
|
userAgent: req.body.userAgent, |
||||
|
token: tokenGenerated, |
||||
|
os: req.body.os, |
||||
|
browser: req.body.browser, |
||||
|
device: req.body.device, |
||||
|
os_version: req.body.os_version, |
||||
|
browser_version: req.body.browser_version, |
||||
|
ip: req.body.ip, |
||||
|
lastLogin: Date() |
||||
|
}; |
||||
|
trainer.tokens.push(newToken); |
||||
|
} else {//userAgent already exist
|
||||
|
trainer.tokens[indexToken].token = ""; |
||||
|
|
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
trainer.tokens[indexToken].token = tokenGenerated; |
||||
|
trainer.tokens[indexToken].ip = req.body.ip; |
||||
|
trainer.tokens[indexToken].lastLogin = Date(); |
||||
|
} |
||||
|
trainer.save(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
// return the information including token as JSON
|
||||
|
trainer.password = ""; |
||||
|
res.json({ |
||||
|
user: trainer, |
||||
|
success: true, |
||||
|
message: 'Enjoy your token!', |
||||
|
token: tokenGenerated |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/trainers/acceptClientPetition' **/ |
||||
|
exports.acceptClientPetition = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token'], role: 'trainer'}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'adding client to trainer failed. trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
console.log(trainer);//aquí potser caldria comprovar que la routine és la que han creat per l'trainer
|
||||
|
//busquem la petition que estem processant
|
||||
|
for (var i = 0; i < trainer.clientsPetitions.length; i++) //routine.days
|
||||
|
{ |
||||
|
if (trainer.clientsPetitions[i]._id.equals(req.body.petitionid)) { |
||||
|
var newClient = { |
||||
|
client: trainer.clientsPetitions[i].clientid, |
||||
|
petitionMessage: trainer.clientsPetitions[i].message, |
||||
|
date: Date() |
||||
|
}; |
||||
|
trainer.clients.push(newClient); |
||||
|
|
||||
|
//la petició la marco com a accepted
|
||||
|
trainer.clientsPetitions[i].state = "accepted"; |
||||
|
trainer.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
userModel.findOne({_id: trainer._id, role: 'trainer'}) |
||||
|
.lean() |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('clients.client', 'name avatar points') |
||||
|
.populate('clientsPetitions.clientid', 'name avatar') |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}); |
||||
|
//ara afegim el trainer al user.trainer
|
||||
|
userModel.findOne({'_id': trainer.clientsPetitions[i].clientid}, function (err, user) { |
||||
|
if (err) console.log(err.message); |
||||
|
if (!user) { |
||||
|
console.log('adding client to trainer failed. user not found.'); |
||||
|
} else if (user) { |
||||
|
user.trainers.push(trainer._id); |
||||
|
|
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "new trainer", |
||||
|
date: Date(), |
||||
|
value: +5 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 5; |
||||
|
/* end of gamification */ |
||||
|
|
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "trainer has accepted to train you", |
||||
|
link: "training", |
||||
|
icon: "newtrainer.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
user.notifications.push(notification); |
||||
|
user.save(function (err) { |
||||
|
if (err) console.log(err.message); |
||||
|
console.log("trainer added to user"); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** PUT '/trainers/:trainerid' **/ |
||||
|
exports.updateTrainer = function (req, res) { |
||||
|
var trainer = req.body; |
||||
|
userModel.update({'tokens.token': req.headers['x-access-token']}, trainer, |
||||
|
function (err) { |
||||
|
if (err) return console.log(err); |
||||
|
console.log(trainer); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/trainers/valorateTrainer/:trainerid' **/ |
||||
|
exports.valorateTrainer = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'sending valoration failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
//ara busquem el trainer
|
||||
|
userModel.findOne({_id: req.params.trainerid, role: 'trainer'}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'sending valoration failed. trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
//comprovem que el client no hagi valorat ja el trainer
|
||||
|
var javalorat = false; |
||||
|
var indexValoration=-1; |
||||
|
for (var i = 0; i < trainer.valorations.length; i++) { |
||||
|
|
||||
|
if (trainer.valorations[i].clientid.equals(user._id)) { |
||||
|
javalorat = true; |
||||
|
indexValoration=JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (javalorat == false) { |
||||
|
var valoration = { |
||||
|
clientid: user._id, |
||||
|
date: Date(), |
||||
|
message: req.body.message, |
||||
|
value: req.body.value |
||||
|
}; |
||||
|
if(!trainer.valoration) |
||||
|
{ |
||||
|
trainer.valoration=0; |
||||
|
} |
||||
|
var actual = (+trainer.valoration) * trainer.valorations.length; |
||||
|
var valor = ((+actual) + (+valoration.value)) / (trainer.valorations.length + 1); |
||||
|
trainer.valoration = valor; |
||||
|
trainer.valorations.push(valoration); |
||||
|
|
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "client has valorated you", |
||||
|
link: "dashboard", |
||||
|
icon: "newvaloration.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
trainer.notifications.push(notification); |
||||
|
|
||||
|
trainer.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
//aquí la gamificació de l'user que fa la valoració per primer cop
|
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "valorating trainer", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
/*if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(routine);*/ |
||||
|
console.log("points of gamification on trainer valorating added to user"); |
||||
|
}); |
||||
|
|
||||
|
userModel.findOne({_id: trainer._id}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('trainers', 'name avatar description') |
||||
|
.populate('clients.client', 'name avatar') |
||||
|
.populate('publications') |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}); |
||||
|
} else {//end if javalorat==false
|
||||
|
console.log("user already has valorated trainer, updating valoration and recalculating total"); |
||||
|
var valoration = { |
||||
|
clientid: user._id, |
||||
|
date: Date(), |
||||
|
message: req.body.message, |
||||
|
value: req.body.value |
||||
|
}; |
||||
|
var actual = ((+trainer.valoration) * (+trainer.valorations.length)) - (+trainer.valorations[indexValoration].value);//suma total valoracions sense la que estic canviant
|
||||
|
var valor = ((+actual) + (+valoration.value)) / (trainer.valorations.length); |
||||
|
console.log(actual + ", " + valor); |
||||
|
trainer.valoration = valor; |
||||
|
trainer.valorations[indexValoration]=valoration; |
||||
|
|
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "client has updated the valoration on you", |
||||
|
link: "dashboard", |
||||
|
icon: "newvaloration.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
trainer.notifications.push(notification); |
||||
|
|
||||
|
trainer.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
userModel.findOne({_id: trainer._id}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('trainers', 'name avatar description') |
||||
|
.populate('clients.client', 'name avatar') |
||||
|
.populate('publications') |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/trainers/:trainerid/getNotifications' **/ |
||||
|
exports.getNotifications = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.trainerid, role: 'trainer'}) |
||||
|
.exec(function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
for (var i = 0; i < trainer.notifications.length; i++) { |
||||
|
if (trainer.notifications[i].state == "pendent") { |
||||
|
trainer.notifications[i].state = "viewed"; |
||||
|
trainer.notifications[i].dateviewed = Date(); |
||||
|
} |
||||
|
} |
||||
|
trainer.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
res.status(200).jsonp(trainer.notifications); |
||||
|
}); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/trainers/searchByName/:trainername' **/ |
||||
|
exports.searchByName = function (req, res) { |
||||
|
console.log("searchByName"); |
||||
|
userModel.find({name: new RegExp(req.params.trainername, "i"), role: 'trainer'}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize)*Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainers); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/trainers/:trainerid' **/ |
||||
|
exports.removeTrainer = function (req, res) {/* AQUESTA FUNCIÖ CREC QUE ESTÂ MAL PLANTEJADA, DIRIA QUE NO FUNCIONA, si jo també ho diria no es pot trobar despres d'eliminar */ |
||||
|
userModel.findByIdAndRemove({_id: req.params.trainerid}, function (err) {/**La he corregit, pero tenint en compte que tenim només un model ara potser es redundant no?**/ |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).send("Trainer Deleted"); |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,791 @@ |
|||||
|
var express = require('express'); |
||||
|
var app = express(); |
||||
|
var router = express.Router(); |
||||
|
var jwt = require('jsonwebtoken'); |
||||
|
var config = require('../config/config'); |
||||
|
var crypto = require('crypto'); |
||||
|
var formidable = require('formidable'); |
||||
|
var fs = require('fs'); |
||||
|
var https = require('https'); |
||||
|
app.set('superSecret', config.secret); |
||||
|
|
||||
|
/*******MODELS*********/ |
||||
|
var publicationModel = require('../models/publicationModel'); |
||||
|
var userModel = require('../models/userModel'); |
||||
|
var dietModel = require('../models/dietModel'); |
||||
|
var routineModel = require('../models/routineModel'); |
||||
|
|
||||
|
|
||||
|
/** POST '/users/register' **/ |
||||
|
exports.register = function (req, res) { |
||||
|
console.log(req.body); |
||||
|
var user = new userModel({ |
||||
|
name: req.body.name, |
||||
|
role: req.body.role, |
||||
|
password: crypto.createHash('sha256').update(req.body.password).digest('base64'), |
||||
|
email: req.body.email, |
||||
|
description: "Hi, i'm here to train.", |
||||
|
avatar: 'img/user.png', |
||||
|
background: 'img/background.png', |
||||
|
attributes: { |
||||
|
height: req.body.height, |
||||
|
weight: req.body.weight, |
||||
|
gender: req.body.gender, |
||||
|
age: req.body.age |
||||
|
}, |
||||
|
points: { |
||||
|
total: 0 |
||||
|
} |
||||
|
}); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "account created", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "Wellcome! this is your profile, update the Profile picture to let other members recognize you", |
||||
|
link: "editUser/" + user._id, |
||||
|
icon: "newpetition.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
user.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
user.save(function (err, user) { |
||||
|
if (err) { |
||||
|
console.log(err.message); |
||||
|
return res.status(500).send(err.message); |
||||
|
} |
||||
|
//res.status(200).jsonp(user); en comptes de retoranr la data del signup, fem el login directament
|
||||
|
console.log("signup fet correctament, redirigint al login internament automàtic"); |
||||
|
exports.login(req, res); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
var SECRET = "6LcyxhIUAAAAAPkCdz5HoBPN5--RhP7mpIE-V2CL"; |
||||
|
|
||||
|
function verifyRecaptcha(key, callback) { |
||||
|
https.get("https://www.google.com/recaptcha/api/siteverify?secret=" + SECRET + "&response=" + key, function(res) { |
||||
|
var data = ""; |
||||
|
res.on('data', function (chunk) { |
||||
|
data += chunk.toString(); |
||||
|
}); |
||||
|
res.on('end', function() { |
||||
|
try { |
||||
|
var parsedData = JSON.parse(data); |
||||
|
callback(parsedData.success); |
||||
|
} catch (e) { |
||||
|
callback(false); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** POST '/users/login' **/ |
||||
|
exports.login = function (req, res) { |
||||
|
verifyRecaptcha(req.body["g-recaptcha-response"], function() { |
||||
|
userModel.findOne({ |
||||
|
email: req.body.email |
||||
|
}) |
||||
|
.select('+password') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) throw err; |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'Authentication failed. User not found.'}); |
||||
|
} else if (user) { |
||||
|
req.body.password = crypto.createHash('sha256').update(req.body.password).digest('base64'); |
||||
|
if (user.password != req.body.password) { |
||||
|
res.json({success: false, message: 'Authentication failed. Wrong password.'}); |
||||
|
} else { |
||||
|
var indexToken = -1; |
||||
|
for (var i = 0; i < user.tokens.length; i++) { |
||||
|
if (user.tokens[i].userAgent == req.body.userAgent) { |
||||
|
indexToken = JSON.parse(JSON.stringify(i));//stringify i parse pq es faci una còpia de la variable i, enlloc de una referència
|
||||
|
} |
||||
|
} |
||||
|
console.log(indexToken); |
||||
|
if (indexToken == -1) {//userAgent no exist
|
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
var newToken = { |
||||
|
userAgent: req.body.userAgent, |
||||
|
token: tokenGenerated, |
||||
|
os: req.body.os, |
||||
|
browser: req.body.browser, |
||||
|
device: req.body.device, |
||||
|
os_version: req.body.os_version, |
||||
|
browser_version: req.body.browser_version, |
||||
|
ip: req.body.ip, |
||||
|
lastLogin: Date() |
||||
|
}; |
||||
|
user.tokens.push(newToken); |
||||
|
} else {//userAgent already exist
|
||||
|
user.tokens[indexToken].token = ""; |
||||
|
var tokenGenerated = jwt.sign({foo: 'bar'}, app.get('superSecret'), { |
||||
|
// expiresIn: 86400 // expires in 24 hours
|
||||
|
}); |
||||
|
user.tokens[indexToken].token = tokenGenerated; |
||||
|
user.tokens[indexToken].ip = req.body.ip; |
||||
|
user.tokens[indexToken].lastLogin = Date(); |
||||
|
} |
||||
|
user.save(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
// return the information including token as JSON
|
||||
|
user.password = ""; |
||||
|
res.json({ |
||||
|
user: user, |
||||
|
success: true, |
||||
|
message: 'Enjoy your token!', |
||||
|
token: tokenGenerated |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
})}; |
||||
|
|
||||
|
/** POST '/logout' **/ |
||||
|
exports.logout = function (req, res, callback) { |
||||
|
var token = req.headers.authorization; |
||||
|
var decoded = verify(token); |
||||
|
if (decoded) { |
||||
|
db.get(decoded.auth, function (err, record) { |
||||
|
if (err) throw err; |
||||
|
var updated = JSON.parse(record); |
||||
|
updated.valid = false; |
||||
|
db.put(decoded.auth, updated, function (err) { |
||||
|
if (err) throw err; |
||||
|
res.writeHead(200, {'content-type': 'text/plain'}); |
||||
|
res.end('Logged Out!'); |
||||
|
return callback(res); |
||||
|
}); |
||||
|
}); |
||||
|
} else { |
||||
|
authFail(res, done); |
||||
|
return callback(res); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/*** Building a File Uploader with NodeJs |
||||
|
* https://coligo.io/building-ajax-file-uploader-with-node/
|
||||
|
*/ |
||||
|
/** POST '/users/upload' **/ |
||||
|
exports.avatarUpload = function (req, res) {/* no sé si s'ha provat si funciona, per ara almenys no està linkat ni es fa servir */ |
||||
|
// create an incoming form object
|
||||
|
var form = new formidable.IncomingForm(); |
||||
|
// specify that we want to allow the user to upload multiple files in a single request
|
||||
|
form.multiples = true; |
||||
|
// store all uploads in the /uploads directory
|
||||
|
form.uploadDir = path.join(__dirname, '/uploads'); |
||||
|
// every time a file has been uploaded successfully,
|
||||
|
// rename it to it's orignal name
|
||||
|
form.on('file', function (field, file) { |
||||
|
fs.rename(file.path, path.join(form.uploadDir, file.name)); |
||||
|
}); |
||||
|
// log any errors that occur
|
||||
|
form.on('error', function (err) { |
||||
|
console.log('An error has occured: \n' + err); |
||||
|
}); |
||||
|
// once all the files have been uploaded, send a response to the client
|
||||
|
form.on('end', function () { |
||||
|
res.end('success'); |
||||
|
}); |
||||
|
// parse the incoming request containing the form data
|
||||
|
form.parse(req); |
||||
|
}; |
||||
|
|
||||
|
/** PUT '/users/:userid' **/ |
||||
|
exports.updateUser = function (req, res) {//funciona
|
||||
|
var id = req.params.userid; |
||||
|
var user = req.body; |
||||
|
userModel.update({'tokens.token': req.headers['x-access-token']}, user, |
||||
|
function (err) { |
||||
|
if (err) return console.log(err); |
||||
|
console.log(user); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE '/users/:userid' **/ |
||||
|
exports.deleteUserById = function (req, res) { |
||||
|
userModel.findByIdAndRemove({_id: req.params.userid}, function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).send("Deleted"); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/' **/ |
||||
|
exports.getUsers = function (req, res) { |
||||
|
userModel.find({role: 'user'}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, users) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(users); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid' **/ |
||||
|
exports.getUserById = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('trainers', 'name avatar description disciplines') |
||||
|
.populate('clients.client', 'name avatar') |
||||
|
.populate('publications') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'User not found.'}); |
||||
|
} else if (user) { |
||||
|
/* aquí va el carro de bucle per acabar retornant només les peticions pendents */ |
||||
|
var pendentNumber=0; |
||||
|
for (var i = 0; i < user.notifications.length; i++) { |
||||
|
if (user.notifications[i].state == "pendent") { |
||||
|
pendentNumber++; |
||||
|
} |
||||
|
} |
||||
|
user.pendentNotificationsNumber=pendentNumber; |
||||
|
/* fi del carro de bucle de peticions pendents */ |
||||
|
res.status(200).jsonp(user); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
exports.getUserByToken = function (req, res) { |
||||
|
console.log(req.params.tok); |
||||
|
userModel.findOne({'tokens.token': req.params.tok}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('trainers', 'name avatar description disciplines') |
||||
|
.populate('clients.client', 'name avatar') |
||||
|
.populate('publications') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'User not found.'}); |
||||
|
} else if (user) { |
||||
|
/* aquí va el carro de bucle per acabar retornant només les peticions pendents */ |
||||
|
var pendentNumber=0; |
||||
|
for (var i = 0; i < user.notifications.length; i++) { |
||||
|
if (user.notifications[i].state == "pendent") { |
||||
|
pendentNumber++; |
||||
|
} |
||||
|
} |
||||
|
user.pendentNotificationsNumber=pendentNumber; |
||||
|
/* fi del carro de bucle de peticions pendents */ |
||||
|
res.status(200).jsonp(user); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid/network' **/ |
||||
|
exports.getUserNetworkById = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}) |
||||
|
.lean() |
||||
|
.populate('followers', 'name avatar description') |
||||
|
.populate('following', 'name avatar description') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid/suggestions' **/ |
||||
|
exports.getUserSuggestionsById = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
|
||||
|
userModel.find({ |
||||
|
$and: [ |
||||
|
{_id: { $nin: user._id}}, |
||||
|
{_id: { $nin: user.following}} |
||||
|
], |
||||
|
city: user.city}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.select('name role email description avatar') |
||||
|
.exec(function (err, users) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
console.log(users); |
||||
|
if (users.length>0) { |
||||
|
res.status(200).jsonp(users); |
||||
|
} else { |
||||
|
//si no té users a la ciutat, li tornem users igualment (tot i no ser de la mateixa ciutat)
|
||||
|
userModel.find({ |
||||
|
$and: [ |
||||
|
{_id: { $nin: user._id}}, |
||||
|
{_id: { $nin: user.following}} |
||||
|
]}) |
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.select('name role email description avatar') |
||||
|
.exec(function (err, users) { |
||||
|
res.status(200).jsonp(users); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid/diets' **/ |
||||
|
exports.getDietsFromUserId = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}) |
||||
|
.populate('diets') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.diets); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid/routines' **/ |
||||
|
exports.getRoutinesFromUserId = function (req, res) { |
||||
|
userModel.findOne({_id: req.params.userid}) |
||||
|
.populate('routines') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.routines); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/users/sendPetitionToTrainer/:trainerid' **/ |
||||
|
exports.sendPetitionToTrainer = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'sending petition failed. user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log(user.name);//aquí potser caldria comprovar que la routine és la que han creat per l'user
|
||||
|
//ara busquem el trainer
|
||||
|
userModel.findOne({_id: req.params.trainerid}, function (err, trainer) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!trainer) { |
||||
|
res.json({success: false, message: 'sending petition failed. trainer not found.'}); |
||||
|
} else if (trainer) { |
||||
|
var newPetition = { |
||||
|
clientid: user._id, |
||||
|
message: req.body.message, |
||||
|
state: "pendent" |
||||
|
}; |
||||
|
trainer.clientsPetitions.push(newPetition); |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: "client has sent a petition to you", |
||||
|
link: "dashboard", |
||||
|
icon: "newpetition.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
trainer.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
trainer.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(trainer); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
exports.getNumberOfNotifications = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'User not found.'}); |
||||
|
} else if (user) { |
||||
|
/* aquí va el carro de bucle per acabar retornant només les peticions pendents */ |
||||
|
var pendentNumber=0; |
||||
|
for (var i = 0; i < user.notifications.length; i++) { |
||||
|
if (user.notifications[i].state == "pendent") { |
||||
|
pendentNumber++; |
||||
|
} |
||||
|
} |
||||
|
/* fi del carro de bucle de peticions pendents */ |
||||
|
res.status(200).jsonp(pendentNumber); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** GET '/users/:userid/getNotifications' **/ |
||||
|
exports.getNotifications = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}) |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'User not found.'}); |
||||
|
} else if (user) { |
||||
|
var viewed=[]; |
||||
|
var pendent=[]; |
||||
|
for (var i = 0; i < user.notifications.length; i++) { |
||||
|
if (user.notifications[i].state == "pendent") { |
||||
|
pendent.push(user.notifications[i]); |
||||
|
user.notifications[i].state = "viewed"; |
||||
|
user.notifications[i].dateviewed = Date(); |
||||
|
}else{ |
||||
|
viewed.push(user.notifications[i]); |
||||
|
} |
||||
|
} |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp({ |
||||
|
pendent: pendent, |
||||
|
viewed: viewed |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** POST '/users/:userid/deleteSelectedTokens' **/ |
||||
|
exports.deleteSelectedTokens = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
console.log(user); |
||||
|
for (var i = 0; i < req.body.devicesToDelete.length; i++) { |
||||
|
for (var j = 0; j < user.tokens.length; j++) { |
||||
|
if (user.tokens[j].userAgent == req.body.devicesToDelete[i].userAgent) { |
||||
|
user.tokens.splice(j, 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
userA: el que fa l'acció de seguir --> se li posa userB a following |
||||
|
userB: el que reb el seguiment --> se li posa el userA al followers |
||||
|
**/ |
||||
|
/** POST '/users/follow' **/ |
||||
|
exports.follow = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userA) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userA) { |
||||
|
res.json({success: false, message: 'userA not found.'}); |
||||
|
} else if (userA) { |
||||
|
//ara busquem el userB
|
||||
|
userModel.findOne({_id: req.body.userid}, function (err, userB) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userB) { |
||||
|
res.json({success: false, message: 'userB not found.'}); |
||||
|
} else if (userB) { |
||||
|
userB.followers.push(userA._id); |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: userA.name + " followed you", |
||||
|
link: "dashboard", |
||||
|
icon: "follower.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
userB.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: userA.name + " followed you", |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
userB.points.history.push(reward); |
||||
|
userB.points.total = userB.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
userB.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userA.following.push(userB._id); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "followed " + userB.name, |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
userA.points.history.push(reward); |
||||
|
userA.points.total = userA.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
userA.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.findOne({_id: userA._id}).lean().populate('following', 'name avatar') |
||||
|
.exec(function (err, userA) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
console.log("user followed" + userB.name); |
||||
|
res.status(200).jsonp(userB); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
userA: el que fa l'acció de deixar de seguir --> se li treu userB de following |
||||
|
userB: el que deixa de tenir el seguiment --> se li treu l'userA del followers |
||||
|
**/ |
||||
|
/** POST '/users/unfollow' **/ |
||||
|
exports.unfollow = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, userA) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userA) { |
||||
|
res.json({success: false, message: 'userA not found.'}); |
||||
|
} else if (userA) { |
||||
|
//ara busquem el userB
|
||||
|
userModel.findOne({_id: req.body.userid}, function (err, userB) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!userB) { |
||||
|
res.json({success: false, message: 'userB not found.'}); |
||||
|
} else if (userB) { |
||||
|
var indexFollower = -1; |
||||
|
for (var i = 0; i < userB.followers.length; i++) { |
||||
|
if (userB.followers[i].equals(userA._id)) { |
||||
|
indexFollower = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
if (indexFollower > -1) { |
||||
|
userB.followers.splice(indexFollower, 1); |
||||
|
/*notification*/ |
||||
|
var notification = { |
||||
|
state: "pendent", |
||||
|
message: userA.name + " unfollowed you", |
||||
|
link: "dashboard", |
||||
|
icon: "unfollower.png", |
||||
|
date: Date() |
||||
|
}; |
||||
|
userB.notifications.push(notification); |
||||
|
/* end of notification*/ |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: userA.name + " unfollowed you", |
||||
|
date: Date(), |
||||
|
value: -1 |
||||
|
}; |
||||
|
userB.points.history.push(reward); |
||||
|
userB.points.total = userB.points.total - 1; |
||||
|
/* end of gamification */ |
||||
|
userB.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
var indexFollower = -1; |
||||
|
for (var i = 0; i < userA.following.length; i++) { |
||||
|
if (userA.following[i].equals(userB._id)) { |
||||
|
indexFollower = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
if (indexFollower > -1) { |
||||
|
userA.following.splice(indexFollower, 1); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "unfollowed " + userB.name, |
||||
|
date: Date(), |
||||
|
value: -1 |
||||
|
}; |
||||
|
userA.points.history.push(reward); |
||||
|
userA.points.total = userA.points.total - 1; |
||||
|
/* end of gamification */ |
||||
|
userA.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.findOne(userA).lean().populate('following', 'name avatar') |
||||
|
.exec(function (err, userA) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
console.log("user followed" + userB.name); |
||||
|
res.status(200).jsonp(userB); |
||||
|
}); |
||||
|
}); |
||||
|
} else {//else de indexFollower>-1
|
||||
|
res.status(200).jsonp({message: 'not found'}); |
||||
|
} |
||||
|
}); |
||||
|
} else {//else de indexFollower>-1
|
||||
|
res.status(200).jsonp({message: 'not found'}); |
||||
|
} |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}//end else if
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/**GET '/search/:searchstring' **/ |
||||
|
exports.search = function (req, res) { |
||||
|
userModel.find({ |
||||
|
name: new RegExp(req.params.searchstring, "i"), |
||||
|
role: 'user' |
||||
|
})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
|
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, users) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.find({ |
||||
|
name: new RegExp(req.params.searchstring, "i"), |
||||
|
role: 'trainer' |
||||
|
})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
|
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, trainers) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
routineModel.find({title: new RegExp(req.params.searchstring, "i")})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
|
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, routines) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
dietModel.find({title: new RegExp(req.params.searchstring, "i")})//perquè retorni tots els objectes que continguin l'string sense necessitat de que sigui exactament la mateixa string
|
||||
|
.limit(Number(req.query.pageSize)) |
||||
|
.skip(Number(req.query.pageSize) * Number(req.query.page)) |
||||
|
.exec(function (err, diets) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.json({ |
||||
|
users: users, |
||||
|
trainers: trainers, |
||||
|
routines: routines, |
||||
|
diets: diets |
||||
|
}); |
||||
|
});//diets
|
||||
|
});//routines
|
||||
|
});//trainers
|
||||
|
});//users
|
||||
|
}; |
||||
|
|
||||
|
/** POST '/users/newMark' **/ |
||||
|
exports.newMark = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
var newmark = { |
||||
|
title: req.body.title, |
||||
|
unit: req.body.unit |
||||
|
}; |
||||
|
user.marks.push(newmark); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "new mark created: " + newmark.title, |
||||
|
date: Date(), |
||||
|
value: +3 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 3; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.marks); |
||||
|
}); |
||||
|
}//end else if user
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** DELETE /users/markid'**/ |
||||
|
exports.deleteUserMark = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
var indexMark=-1; |
||||
|
for (var i = 0; i < user.marks.length; i++) { |
||||
|
if (user.marks[i]._id == req.params.markid) { |
||||
|
indexMark = JSON.parse(JSON.stringify(i)); |
||||
|
} |
||||
|
} |
||||
|
if(indexMark>-1) |
||||
|
{ |
||||
|
user.marks.splice(indexMark, 1); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "mark deleted", |
||||
|
date: Date(), |
||||
|
value: -3 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total - 3; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err, user) {//guardem el trainer amb la rutina treta
|
||||
|
if (err) return res.send(500, err.message); |
||||
|
userModel.findOne({_id: user._id}) |
||||
|
.lean() |
||||
|
.populate('diets', 'title description') |
||||
|
.populate('routines', 'title description') |
||||
|
.populate('trainers', 'name avatar description disciplines') |
||||
|
.populate('clients.client', 'name avatar') |
||||
|
.populate('publications') |
||||
|
.exec(function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user); |
||||
|
}); |
||||
|
}); |
||||
|
}else{ |
||||
|
res.status(200).jsonp({message: 'mark not found'}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
cal rebre: |
||||
|
_id |
||||
|
value: 10 |
||||
|
**/ |
||||
|
/** POST '/users/:markid/addDayToMark' **/ |
||||
|
exports.addDayToMark = function (req, res) { |
||||
|
userModel.findOne({'tokens.token': req.headers['x-access-token']}, function (err, user) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
if (!user) { |
||||
|
res.json({success: false, message: 'user not found.'}); |
||||
|
} else if (user) { |
||||
|
var indexMark = -1; |
||||
|
var indexDay = -1; |
||||
|
for (var i = 0; i < user.marks.length; i++) { |
||||
|
if (user.marks[i]._id == req.params.markid) { |
||||
|
indexMark = JSON.parse(JSON.stringify(i)); |
||||
|
for (var j = 0; j < user.marks[i].days.length; j++) { |
||||
|
if (user.marks[i].days[j].date == Date()) { |
||||
|
indexDay = JSON.parse(JSON.stringify(j)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (indexMark > -1)//si la mark existeix
|
||||
|
{ |
||||
|
if (indexDay == -1)//però el dia no existeix encara
|
||||
|
{ |
||||
|
var newday = { |
||||
|
date: Date(), |
||||
|
value: req.body.value |
||||
|
}; |
||||
|
user.marks[indexMark].days.push(newday); |
||||
|
/* gamification */ |
||||
|
var reward = { |
||||
|
concept: "day value added to mark: " + user.marks[indexMark].title, |
||||
|
date: Date(), |
||||
|
value: +1 |
||||
|
}; |
||||
|
user.points.history.push(reward); |
||||
|
user.points.total = user.points.total + 1; |
||||
|
/* end of gamification */ |
||||
|
user.save(function (err) { |
||||
|
if (err) return res.send(500, err.message); |
||||
|
res.status(200).jsonp(user.marks); |
||||
|
}); |
||||
|
} else { |
||||
|
res.status(200).jsonp({message: 'mark of day already registered'}); |
||||
|
} |
||||
|
} else { |
||||
|
res.status(200).jsonp({message: 'mark not registered'}); |
||||
|
} |
||||
|
}//end else if user
|
||||
|
}); |
||||
|
}; |
@ -0,0 +1,12 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var contactSchema = new Schema({ |
||||
|
name: {type: String, required: true,}, |
||||
|
subject: {type: String, required: true, select: false}, |
||||
|
email: {type: String, required: true, unique: true}, |
||||
|
description: {type: String} |
||||
|
}); |
||||
|
contactSchema.plugin(mongooseUniqueValidator); |
||||
|
module.exports = mongoose.model('contactModel', contactSchema); |
@ -0,0 +1,27 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var conversationSchema = new Schema({ |
||||
|
userA: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
userB: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
messages: [{ |
||||
|
user: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
content: {type: String}, |
||||
|
date: {type: Date} |
||||
|
}], |
||||
|
modifiedDate: {type: Date} |
||||
|
}); |
||||
|
|
||||
|
conversationSchema.plugin(mongooseUniqueValidator); |
||||
|
|
||||
|
module.exports = mongoose.model('conversationModel', conversationSchema); |
@ -0,0 +1,46 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var dietSchema = new Schema({ |
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
startingDay: {type: Date}, |
||||
|
price: { type: Number }, |
||||
|
image: { type: String }, |
||||
|
clients: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}], |
||||
|
chef: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
days: [{ |
||||
|
date: {type: Date}, //Ha de ser realmente un día que empiezas por ejemplo 12/12/2016 para poder ir completando según la fecha, comer comes cada día
|
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
meals: [{ |
||||
|
title: {type: String}, |
||||
|
img: {type: String}, |
||||
|
submeals: [{ |
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
amount: { |
||||
|
unit: {type: String}, |
||||
|
quantity: {type: Number} |
||||
|
}, |
||||
|
nutritional: { |
||||
|
kcal: {type: Number}, |
||||
|
proteins: {type: Number}, |
||||
|
carbohidrates: {type: Number}, |
||||
|
fats: {type: Number}, |
||||
|
vitamins: {type: Number} |
||||
|
} |
||||
|
}] |
||||
|
}], |
||||
|
done: {type: Boolean, default: false} |
||||
|
}] |
||||
|
}); |
||||
|
dietSchema.plugin(mongooseUniqueValidator); |
||||
|
module.exports = mongoose.model('dietModel', dietSchema); |
@ -0,0 +1,22 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var publicationSchema = new Schema({ |
||||
|
title: {type: String, required: true}, |
||||
|
content: {type: String, required: true}, |
||||
|
user: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
photo: {type: String},//link a la imatge, en plan, l'user corrent pel carrer tot feliç
|
||||
|
date: {type: Date}, |
||||
|
likes: [{ |
||||
|
type:mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}] |
||||
|
}); |
||||
|
|
||||
|
publicationSchema.plugin(mongooseUniqueValidator); |
||||
|
|
||||
|
module.exports = mongoose.model('publicationModel', publicationSchema); |
@ -0,0 +1,37 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var routineSchema = new Schema({ |
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
startingDay: {type: Date}, |
||||
|
discipline: {type: String}, |
||||
|
price: { type: Number },//si és gratis, es posa q val 0, així els users ho veuen amb bons ulls
|
||||
|
image: { type: String }, |
||||
|
client: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
trainer: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
days: [{ |
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
exercises: [{ |
||||
|
title: {type: String}, |
||||
|
description: {type: String}, |
||||
|
img: {type: String}, |
||||
|
weight: {type: String}, |
||||
|
distance: {type: String}, |
||||
|
reps: {type: String}, |
||||
|
series: {type: String} |
||||
|
}], |
||||
|
done: {type: String, default: false}//si ha complert el dia
|
||||
|
}] |
||||
|
}) |
||||
|
; |
||||
|
routineSchema.plugin(mongooseUniqueValidator); |
||||
|
module.exports = mongoose.model('routineModel', routineSchema); |
@ -0,0 +1,25 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
|
||||
|
var runSchema = new Schema({ |
||||
|
title: {type: String}, |
||||
|
photo: {type: String}, |
||||
|
user: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
datestart: {type: Date}, |
||||
|
datefinish: {type: Date}, |
||||
|
distance: {type: Number}, |
||||
|
positions: [{ |
||||
|
date: {type: Date}, |
||||
|
lat: {type: Number}, |
||||
|
long: {type: Number}, |
||||
|
distance: {type: Number} |
||||
|
}] |
||||
|
}); |
||||
|
|
||||
|
runSchema.plugin(mongooseUniqueValidator); |
||||
|
|
||||
|
module.exports = mongoose.model('runModel', runSchema); |
@ -0,0 +1,140 @@ |
|||||
|
var mongoose = require('mongoose'); |
||||
|
var mongooseUniqueValidator = require('mongoose-unique-validator'); |
||||
|
var Schema = mongoose.Schema; |
||||
|
var userSchema = new Schema({ |
||||
|
name: {type: String, required: true, unique: true}, |
||||
|
role: {type: String, required: true}, |
||||
|
password: {type: String, select: false}, |
||||
|
tokens: [{ |
||||
|
userAgent: {type: String}, |
||||
|
token: {type: String}, |
||||
|
os: {type: String}, |
||||
|
browser: {type: String}, |
||||
|
device: {type: String}, |
||||
|
os_version: {type: String}, |
||||
|
browser_version: {type: String}, |
||||
|
ip: {type: String}, |
||||
|
lastLogin: {type: Date}, |
||||
|
birthdate: {type: Date}, |
||||
|
}], |
||||
|
testimonial: {type :String},//Para la landing page, sera como una review del sitio
|
||||
|
email: {type: String, required: true, unique: true}, |
||||
|
description: {type: String}, |
||||
|
direction: {type: String}, |
||||
|
city: {type: String}, |
||||
|
avatar: {type: String}, |
||||
|
background: {type: String}, |
||||
|
attributes: { |
||||
|
height: {type: Number}, |
||||
|
weight: {type: Number}, |
||||
|
gender: {type: String},//Home, Dona, Altres -->com a mínim aquestes 3 opcions, més endavant tenim el debat de com s'enfoca
|
||||
|
age: {type: Number} |
||||
|
}, |
||||
|
publications: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'publicationModel' |
||||
|
}], |
||||
|
runs: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'runModel' |
||||
|
}], |
||||
|
totalkm: {type: Number}, |
||||
|
conversations: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'conversationModel' |
||||
|
}], |
||||
|
diets: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'dietModel' |
||||
|
}], |
||||
|
trainers: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}], |
||||
|
routines: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'routineModel' |
||||
|
}],// trainermodel
|
||||
|
disciplines : [{ |
||||
|
name: {type: String} |
||||
|
}], |
||||
|
specialties : [{ |
||||
|
name: {type: String} |
||||
|
}], |
||||
|
clients: [{ |
||||
|
client: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
petitionMessage: {type: String}, |
||||
|
date: {type: Date} |
||||
|
}], |
||||
|
clientsPetitions: [{ |
||||
|
clientid: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
message: {type: String}, |
||||
|
state: {type: String}//pendent, accepted, declined
|
||||
|
}], |
||||
|
valoration: {type:String}, //La media de todas las valoraciones
|
||||
|
valorations: [{ |
||||
|
clientid: { |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}, |
||||
|
date: {type: Date}, |
||||
|
message: {type: String},//missatge de valoració
|
||||
|
value: {type: Number}//per exemple sistema d'estrelles sobre 5
|
||||
|
}],//end of trainermodel
|
||||
|
points: { |
||||
|
total: {type: Number}, |
||||
|
history: [{ |
||||
|
concept: {type: String}, |
||||
|
date: {type: Date}, |
||||
|
value: {type: Number} |
||||
|
}] |
||||
|
}, |
||||
|
marks: [{ |
||||
|
title: {type: String}, |
||||
|
unit: {type: String},//si són kg, km
|
||||
|
best: { |
||||
|
date: {type: Date}, |
||||
|
value: {type: String} |
||||
|
}, |
||||
|
days:[{ |
||||
|
date: {type: Date}, |
||||
|
value: {type: String} |
||||
|
}] |
||||
|
}], |
||||
|
notifications: [{ |
||||
|
state: {type: String},//viewed, pendent
|
||||
|
message: {type: String}, |
||||
|
link: {type: String},//aquí oju, a la app i a la web calen links diferents, però ho podem fer posant sempre a la app i a la web el prefix del link (#!/app) o (#/app/), i després afegint-hi la pàgina on volem enviar el routing, per exemple (dashboard)
|
||||
|
icon: {type: String}, |
||||
|
date: {type: Date}, |
||||
|
dateviewed: {type: Date} |
||||
|
}], |
||||
|
followers: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}], |
||||
|
following: [{ |
||||
|
type: mongoose.Schema.Types.ObjectId, |
||||
|
ref: 'userModel' |
||||
|
}], |
||||
|
google: { |
||||
|
id: {type: String}, |
||||
|
token: {type: String}, |
||||
|
email: {type: String}, |
||||
|
name: {type: String}, |
||||
|
}, |
||||
|
twitter: { |
||||
|
id: {type: String}, |
||||
|
token: {type: String}, |
||||
|
email: {type: String}, |
||||
|
name: {type: String}, |
||||
|
} |
||||
|
}); |
||||
|
userSchema.plugin(mongooseUniqueValidator); |
||||
|
module.exports = mongoose.model('userModel', userSchema); |
@ -0,0 +1,74 @@ |
|||||
|
1.1.4 / 2014-12-10 |
||||
|
================== |
||||
|
|
||||
|
* deps: mime-types@~2.0.4 |
||||
|
- deps: mime-db@~1.3.0 |
||||
|
|
||||
|
1.1.3 / 2014-11-09 |
||||
|
================== |
||||
|
|
||||
|
* deps: mime-types@~2.0.3 |
||||
|
- deps: mime-db@~1.2.0 |
||||
|
|
||||
|
1.1.2 / 2014-10-14 |
||||
|
================== |
||||
|
|
||||
|
* deps: negotiator@0.4.9 |
||||
|
- Fix error when media type has invalid parameter |
||||
|
|
||||
|
1.1.1 / 2014-09-28 |
||||
|
================== |
||||
|
|
||||
|
* deps: mime-types@~2.0.2 |
||||
|
- deps: mime-db@~1.1.0 |
||||
|
* deps: negotiator@0.4.8 |
||||
|
- Fix all negotiations to be case-insensitive |
||||
|
- Stable sort preferences of same quality according to client order |
||||
|
|
||||
|
1.1.0 / 2014-09-02 |
||||
|
================== |
||||
|
|
||||
|
* update `mime-types` |
||||
|
|
||||
|
1.0.7 / 2014-07-04 |
||||
|
================== |
||||
|
|
||||
|
* Fix wrong type returned from `type` when match after unknown extension |
||||
|
|
||||
|
1.0.6 / 2014-06-24 |
||||
|
================== |
||||
|
|
||||
|
* deps: negotiator@0.4.7 |
||||
|
|
||||
|
1.0.5 / 2014-06-20 |
||||
|
================== |
||||
|
|
||||
|
* fix crash when unknown extension given |
||||
|
|
||||
|
1.0.4 / 2014-06-19 |
||||
|
================== |
||||
|
|
||||
|
* use `mime-types` |
||||
|
|
||||
|
1.0.3 / 2014-06-11 |
||||
|
================== |
||||
|
|
||||
|
* deps: negotiator@0.4.6 |
||||
|
- Order by specificity when quality is the same |
||||
|
|
||||
|
1.0.2 / 2014-05-29 |
||||
|
================== |
||||
|
|
||||
|
* Fix interpretation when header not in request |
||||
|
* deps: pin negotiator@0.4.5 |
||||
|
|
||||
|
1.0.1 / 2014-01-18 |
||||
|
================== |
||||
|
|
||||
|
* Identity encoding isn't always acceptable |
||||
|
* deps: negotiator@~0.4.0 |
||||
|
|
||||
|
1.0.0 / 2013-12-27 |
||||
|
================== |
||||
|
|
||||
|
* Genesis |
@ -0,0 +1,22 @@ |
|||||
|
(The MIT License) |
||||
|
|
||||
|
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining |
||||
|
a copy of this software and associated documentation files (the |
||||
|
'Software'), to deal in the Software without restriction, including |
||||
|
without limitation the rights to use, copy, modify, merge, publish, |
||||
|
distribute, sublicense, and/or sell copies of the Software, and to |
||||
|
permit persons to whom the Software is furnished to do so, subject to |
||||
|
the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be |
||||
|
included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, |
||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,94 @@ |
|||||
|
# accepts |
||||
|
|
||||
|
[![NPM Version][npm-image]][npm-url] |
||||
|
[![NPM Downloads][downloads-image]][downloads-url] |
||||
|
[![Node.js Version][node-version-image]][node-version-url] |
||||
|
[![Build Status][travis-image]][travis-url] |
||||
|
[![Test Coverage][coveralls-image]][coveralls-url] |
||||
|
|
||||
|
Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use. |
||||
|
|
||||
|
In addition to negotatior, it allows: |
||||
|
|
||||
|
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`. |
||||
|
- Allows type shorthands such as `json`. |
||||
|
- Returns `false` when no types match |
||||
|
- Treats non-existent headers as `*` |
||||
|
|
||||
|
## API |
||||
|
|
||||
|
### var accept = new Accepts(req) |
||||
|
|
||||
|
```js |
||||
|
var accepts = require('accepts') |
||||
|
|
||||
|
http.createServer(function (req, res) { |
||||
|
var accept = accepts(req) |
||||
|
}) |
||||
|
``` |
||||
|
|
||||
|
### accept\[property\]\(\) |
||||
|
|
||||
|
Returns all the explicitly accepted content property as an array in descending priority. |
||||
|
|
||||
|
- `accept.types()` |
||||
|
- `accept.encodings()` |
||||
|
- `accept.charsets()` |
||||
|
- `accept.languages()` |
||||
|
|
||||
|
They are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc. |
||||
|
|
||||
|
Note: you should almost never do this in a real app as it defeats the purpose of content negotiation. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
```js |
||||
|
// in Google Chrome |
||||
|
var encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate'] |
||||
|
``` |
||||
|
|
||||
|
Since you probably don't support `sdch`, you should just supply the encodings you support: |
||||
|
|
||||
|
```js |
||||
|
var encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably |
||||
|
``` |
||||
|
|
||||
|
### accept\[property\]\(values, ...\) |
||||
|
|
||||
|
You can either have `values` be an array or have an argument list of values. |
||||
|
|
||||
|
If the client does not accept any `values`, `false` will be returned. |
||||
|
If the client accepts any `values`, the preferred `value` will be return. |
||||
|
|
||||
|
For `accept.types()`, shorthand mime types are allowed. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
```js |
||||
|
// req.headers.accept = 'application/json' |
||||
|
|
||||
|
accept.types('json') // -> 'json' |
||||
|
accept.types('html', 'json') // -> 'json' |
||||
|
accept.types('html') // -> false |
||||
|
|
||||
|
// req.headers.accept = '' |
||||
|
// which is equivalent to `*` |
||||
|
|
||||
|
accept.types() // -> [], no explicit types |
||||
|
accept.types('text/html', 'text/json') // -> 'text/html', since it was first |
||||
|
``` |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
[MIT](LICENSE) |
||||
|
|
||||
|
[npm-image]: https://img.shields.io/npm/v/accepts.svg?style=flat |
||||
|
[npm-url]: https://npmjs.org/package/accepts |
||||
|
[node-version-image]: https://img.shields.io/node/v/accepts.svg?style=flat |
||||
|
[node-version-url]: http://nodejs.org/download/ |
||||
|
[travis-image]: https://img.shields.io/travis/jshttp/accepts.svg?style=flat |
||||
|
[travis-url]: https://travis-ci.org/jshttp/accepts |
||||
|
[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts.svg?style=flat |
||||
|
[coveralls-url]: https://coveralls.io/r/jshttp/accepts |
||||
|
[downloads-image]: https://img.shields.io/npm/dm/accepts.svg?style=flat |
||||
|
[downloads-url]: https://npmjs.org/package/accepts |
@ -0,0 +1,160 @@ |
|||||
|
var Negotiator = require('negotiator') |
||||
|
var mime = require('mime-types') |
||||
|
|
||||
|
var slice = [].slice |
||||
|
|
||||
|
module.exports = Accepts |
||||
|
|
||||
|
function Accepts(req) { |
||||
|
if (!(this instanceof Accepts)) |
||||
|
return new Accepts(req) |
||||
|
|
||||
|
this.headers = req.headers |
||||
|
this.negotiator = Negotiator(req) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check if the given `type(s)` is acceptable, returning |
||||
|
* the best match when true, otherwise `undefined`, in which |
||||
|
* case you should respond with 406 "Not Acceptable". |
||||
|
* |
||||
|
* The `type` value may be a single mime type string |
||||
|
* such as "application/json", the extension name |
||||
|
* such as "json" or an array `["json", "html", "text/plain"]`. When a list |
||||
|
* or array is given the _best_ match, if any is returned. |
||||
|
* |
||||
|
* Examples: |
||||
|
* |
||||
|
* // Accept: text/html
|
||||
|
* this.types('html'); |
||||
|
* // => "html"
|
||||
|
* |
||||
|
* // Accept: text/*, application/json
|
||||
|
* this.types('html'); |
||||
|
* // => "html"
|
||||
|
* this.types('text/html'); |
||||
|
* // => "text/html"
|
||||
|
* this.types('json', 'text'); |
||||
|
* // => "json"
|
||||
|
* this.types('application/json'); |
||||
|
* // => "application/json"
|
||||
|
* |
||||
|
* // Accept: text/*, application/json
|
||||
|
* this.types('image/png'); |
||||
|
* this.types('png'); |
||||
|
* // => undefined
|
||||
|
* |
||||
|
* // Accept: text/*;q=.5, application/json
|
||||
|
* this.types(['html', 'json']); |
||||
|
* this.types('html', 'json'); |
||||
|
* // => "json"
|
||||
|
* |
||||
|
* @param {String|Array} type(s)... |
||||
|
* @return {String|Array|Boolean} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Accepts.prototype.type = |
||||
|
Accepts.prototype.types = function (types) { |
||||
|
if (!Array.isArray(types)) types = slice.call(arguments); |
||||
|
var n = this.negotiator; |
||||
|
if (!types.length) return n.mediaTypes(); |
||||
|
if (!this.headers.accept) return types[0]; |
||||
|
var mimes = types.map(extToMime); |
||||
|
var accepts = n.mediaTypes(mimes.filter(validMime)); |
||||
|
var first = accepts[0]; |
||||
|
if (!first) return false; |
||||
|
return types[mimes.indexOf(first)]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return accepted encodings or best fit based on `encodings`. |
||||
|
* |
||||
|
* Given `Accept-Encoding: gzip, deflate` |
||||
|
* an array sorted by quality is returned: |
||||
|
* |
||||
|
* ['gzip', 'deflate'] |
||||
|
* |
||||
|
* @param {String|Array} encoding(s)... |
||||
|
* @return {String|Array} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Accepts.prototype.encoding = |
||||
|
Accepts.prototype.encodings = function (encodings) { |
||||
|
if (!Array.isArray(encodings)) encodings = slice.call(arguments); |
||||
|
var n = this.negotiator; |
||||
|
if (!encodings.length) return n.encodings(); |
||||
|
return n.encodings(encodings)[0] || false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return accepted charsets or best fit based on `charsets`. |
||||
|
* |
||||
|
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` |
||||
|
* an array sorted by quality is returned: |
||||
|
* |
||||
|
* ['utf-8', 'utf-7', 'iso-8859-1'] |
||||
|
* |
||||
|
* @param {String|Array} charset(s)... |
||||
|
* @return {String|Array} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Accepts.prototype.charset = |
||||
|
Accepts.prototype.charsets = function (charsets) { |
||||
|
if (!Array.isArray(charsets)) charsets = [].slice.call(arguments); |
||||
|
var n = this.negotiator; |
||||
|
if (!charsets.length) return n.charsets(); |
||||
|
if (!this.headers['accept-charset']) return charsets[0]; |
||||
|
return n.charsets(charsets)[0] || false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return accepted languages or best fit based on `langs`. |
||||
|
* |
||||
|
* Given `Accept-Language: en;q=0.8, es, pt` |
||||
|
* an array sorted by quality is returned: |
||||
|
* |
||||
|
* ['es', 'pt', 'en'] |
||||
|
* |
||||
|
* @param {String|Array} lang(s)... |
||||
|
* @return {Array|String} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Accepts.prototype.lang = |
||||
|
Accepts.prototype.langs = |
||||
|
Accepts.prototype.language = |
||||
|
Accepts.prototype.languages = function (langs) { |
||||
|
if (!Array.isArray(langs)) langs = slice.call(arguments); |
||||
|
var n = this.negotiator; |
||||
|
if (!langs.length) return n.languages(); |
||||
|
if (!this.headers['accept-language']) return langs[0]; |
||||
|
return n.languages(langs)[0] || false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Convert extnames to mime. |
||||
|
* |
||||
|
* @param {String} type |
||||
|
* @return {String} |
||||
|
* @api private |
||||
|
*/ |
||||
|
|
||||
|
function extToMime(type) { |
||||
|
if (~type.indexOf('/')) return type; |
||||
|
return mime.lookup(type); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check if mime is valid. |
||||
|
* |
||||
|
* @param {String} type |
||||
|
* @return {String} |
||||
|
* @api private |
||||
|
*/ |
||||
|
|
||||
|
function validMime(type) { |
||||
|
return typeof type === 'string'; |
||||
|
} |
@ -0,0 +1,125 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "accepts@~1.1.3", |
||||
|
"scope": null, |
||||
|
"escapedName": "accepts", |
||||
|
"name": "accepts", |
||||
|
"rawSpec": "~1.1.3", |
||||
|
"spec": ">=1.1.3 <1.2.0", |
||||
|
"type": "range" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/express" |
||||
|
] |
||||
|
], |
||||
|
"_from": "accepts@>=1.1.3 <1.2.0", |
||||
|
"_id": "accepts@1.1.4", |
||||
|
"_inCache": true, |
||||
|
"_location": "/accepts", |
||||
|
"_npmUser": { |
||||
|
"name": "dougwilson", |
||||
|
"email": "doug@somethingdoug.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.4.21", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "accepts@~1.1.3", |
||||
|
"scope": null, |
||||
|
"escapedName": "accepts", |
||||
|
"name": "accepts", |
||||
|
"rawSpec": "~1.1.3", |
||||
|
"spec": ">=1.1.3 <1.2.0", |
||||
|
"type": "range" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/express" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", |
||||
|
"_shasum": "d71c96f7d41d0feda2c38cd14e8a27c04158df4a", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "accepts@~1.1.3", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/express", |
||||
|
"author": { |
||||
|
"name": "Jonathan Ong", |
||||
|
"email": "me@jongleberry.com", |
||||
|
"url": "http://jongleberry.com" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/jshttp/accepts/issues" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"mime-types": "~2.0.4", |
||||
|
"negotiator": "0.4.9" |
||||
|
}, |
||||
|
"description": "Higher-level content negotiation", |
||||
|
"devDependencies": { |
||||
|
"istanbul": "~0.3.4", |
||||
|
"mocha": "~2.0.1" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "d71c96f7d41d0feda2c38cd14e8a27c04158df4a", |
||||
|
"tarball": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 0.8" |
||||
|
}, |
||||
|
"files": [ |
||||
|
"LICENSE", |
||||
|
"HISTORY.md", |
||||
|
"index.js" |
||||
|
], |
||||
|
"gitHead": "df66414d80f096627b28f137127fce0a851d7900", |
||||
|
"homepage": "https://github.com/jshttp/accepts", |
||||
|
"keywords": [ |
||||
|
"content", |
||||
|
"negotiation", |
||||
|
"accept", |
||||
|
"accepts" |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "jongleberry", |
||||
|
"email": "jonathanrichardong@gmail.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "federomero", |
||||
|
"email": "federomero@gmail.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "dougwilson", |
||||
|
"email": "doug@somethingdoug.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "tjholowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "shtylman", |
||||
|
"email": "shtylman@gmail.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "mscdex", |
||||
|
"email": "mscdex@mscdex.net" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "fishrock123", |
||||
|
"email": "fishrock123@rocketmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "accepts", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/jshttp/accepts.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "mocha --reporter spec --check-leaks --bail test/", |
||||
|
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", |
||||
|
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" |
||||
|
}, |
||||
|
"version": "1.1.4" |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
node_modules |
||||
|
.monitor |
@ -0,0 +1,12 @@ |
|||||
|
language: node_js |
||||
|
node_js: |
||||
|
- 0.6 |
||||
|
- 0.8 |
||||
|
- 0.9 |
||||
|
- 0.10 |
||||
|
- 0.12 |
||||
|
- 4.2.4 |
||||
|
- 5.4.1 |
||||
|
- iojs-1 |
||||
|
- iojs-2 |
||||
|
- iojs-3 |
@ -0,0 +1,19 @@ |
|||||
|
Copyright (c) 2011 Raynos. |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,115 @@ |
|||||
|
# After [![Build Status][1]][2] |
||||
|
|
||||
|
Invoke callback after n calls |
||||
|
|
||||
|
## Status: production ready |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
```js |
||||
|
var after = require("after") |
||||
|
var db = require("./db") // some db. |
||||
|
|
||||
|
var updateUser = function (req, res) { |
||||
|
// use after to run two tasks in parallel, |
||||
|
// namely get request body and get session |
||||
|
// then run updateUser with the results |
||||
|
var next = after(2, updateUser) |
||||
|
var results = {} |
||||
|
|
||||
|
getJSONBody(req, res, function (err, body) { |
||||
|
if (err) return next(err) |
||||
|
|
||||
|
results.body = body |
||||
|
next(null, results) |
||||
|
}) |
||||
|
|
||||
|
getSessionUser(req, res, function (err, user) { |
||||
|
if (err) return next(err) |
||||
|
|
||||
|
results.user = user |
||||
|
next(null, results) |
||||
|
}) |
||||
|
|
||||
|
// now do the thing! |
||||
|
function updateUser(err, result) { |
||||
|
if (err) { |
||||
|
res.statusCode = 500 |
||||
|
return res.end("Unexpected Error") |
||||
|
} |
||||
|
|
||||
|
if (!result.user || result.user.role !== "admin") { |
||||
|
res.statusCode = 403 |
||||
|
return res.end("Permission Denied") |
||||
|
} |
||||
|
|
||||
|
db.put("users:" + req.params.userId, result.body, function (err) { |
||||
|
if (err) { |
||||
|
res.statusCode = 500 |
||||
|
return res.end("Unexpected Error") |
||||
|
} |
||||
|
|
||||
|
res.statusCode = 200 |
||||
|
res.end("Ok") |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Naive Example |
||||
|
|
||||
|
```js |
||||
|
var after = require("after") |
||||
|
, next = after(3, logItWorks) |
||||
|
|
||||
|
next() |
||||
|
next() |
||||
|
next() // it works |
||||
|
|
||||
|
function logItWorks() { |
||||
|
console.log("it works!") |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Example with error handling |
||||
|
|
||||
|
```js |
||||
|
var after = require("after") |
||||
|
, next = after(3, logError) |
||||
|
|
||||
|
next() |
||||
|
next(new Error("oops")) // logs oops |
||||
|
next() // does nothing |
||||
|
|
||||
|
// This callback is only called once. |
||||
|
// If there is an error the callback gets called immediately |
||||
|
// this avoids the situation where errors get lost. |
||||
|
function logError(err) { |
||||
|
console.log(err) |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
`npm install after` |
||||
|
|
||||
|
## Tests |
||||
|
|
||||
|
`npm test` |
||||
|
|
||||
|
## Contributors |
||||
|
|
||||
|
- Raynos |
||||
|
- defunctzombie |
||||
|
|
||||
|
## MIT Licenced |
||||
|
|
||||
|
[1]: https://secure.travis-ci.org/Raynos/after.png |
||||
|
[2]: http://travis-ci.org/Raynos/after |
||||
|
[3]: http://raynos.org/blog/2/Flow-control-in-node.js |
||||
|
[4]: http://stackoverflow.com/questions/6852059/determining-the-end-of-asynchronous-operations-javascript/6852307#6852307 |
||||
|
[5]: http://stackoverflow.com/questions/6869872/in-javascript-what-are-best-practices-for-executing-multiple-asynchronous-functi/6870031#6870031 |
||||
|
[6]: http://stackoverflow.com/questions/6864397/javascript-performance-long-running-tasks/6889419#6889419 |
||||
|
[7]: http://stackoverflow.com/questions/6597493/synchronous-database-queries-with-node-js/6620091#6620091 |
||||
|
[8]: http://github.com/Raynos/iterators |
||||
|
[9]: http://github.com/Raynos/composite |
@ -0,0 +1,28 @@ |
|||||
|
module.exports = after |
||||
|
|
||||
|
function after(count, callback, err_cb) { |
||||
|
var bail = false |
||||
|
err_cb = err_cb || noop |
||||
|
proxy.count = count |
||||
|
|
||||
|
return (count === 0) ? callback() : proxy |
||||
|
|
||||
|
function proxy(err, result) { |
||||
|
if (proxy.count <= 0) { |
||||
|
throw new Error('after called too many times') |
||||
|
} |
||||
|
--proxy.count |
||||
|
|
||||
|
// after first error, rest are passed to err_cb
|
||||
|
if (err) { |
||||
|
bail = true |
||||
|
callback(err) |
||||
|
// future error callbacks will go to error handler
|
||||
|
callback = err_cb |
||||
|
} else if (proxy.count === 0 && !bail) { |
||||
|
callback(null, result) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function noop() {} |
@ -0,0 +1,103 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "after@0.8.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "after", |
||||
|
"name": "after", |
||||
|
"rawSpec": "0.8.2", |
||||
|
"spec": "0.8.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser" |
||||
|
] |
||||
|
], |
||||
|
"_from": "after@0.8.2", |
||||
|
"_id": "after@0.8.2", |
||||
|
"_inCache": true, |
||||
|
"_location": "/after", |
||||
|
"_nodeVersion": "0.10.32", |
||||
|
"_npmOperationalInternal": { |
||||
|
"host": "packages-12-west.internal.npmjs.com", |
||||
|
"tmp": "tmp/after-0.8.2.tgz_1471308639186_0.9132961586583406" |
||||
|
}, |
||||
|
"_npmUser": { |
||||
|
"name": "raynos", |
||||
|
"email": "raynos2@gmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "2.15.9", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "after@0.8.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "after", |
||||
|
"name": "after", |
||||
|
"rawSpec": "0.8.2", |
||||
|
"spec": "0.8.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io-parser" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", |
||||
|
"_shasum": "fedb394f9f0e02aa9768e702bda23b505fae7e1f", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "after@0.8.2", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser", |
||||
|
"author": { |
||||
|
"name": "Raynos", |
||||
|
"email": "raynos2@gmail.com" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/Raynos/after/issues" |
||||
|
}, |
||||
|
"contributors": [ |
||||
|
{ |
||||
|
"name": "Raynos", |
||||
|
"email": "raynos2@gmail.com", |
||||
|
"url": "http://raynos.org" |
||||
|
} |
||||
|
], |
||||
|
"dependencies": {}, |
||||
|
"description": "after - tiny flow control", |
||||
|
"devDependencies": { |
||||
|
"mocha": "~1.8.1" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "fedb394f9f0e02aa9768e702bda23b505fae7e1f", |
||||
|
"tarball": "https://registry.npmjs.org/after/-/after-0.8.2.tgz" |
||||
|
}, |
||||
|
"gitHead": "e8c26046f36962b90e68dc5df33a9672a54b25f5", |
||||
|
"homepage": "https://github.com/Raynos/after#readme", |
||||
|
"keywords": [ |
||||
|
"flowcontrol", |
||||
|
"after", |
||||
|
"flow", |
||||
|
"control", |
||||
|
"arch" |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "raynos", |
||||
|
"email": "raynos2@gmail.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "defunctzombie", |
||||
|
"email": "shtylman@gmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "after", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git://github.com/Raynos/after.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "mocha --ui tdd --reporter spec test/*.js" |
||||
|
}, |
||||
|
"version": "0.8.2" |
||||
|
} |
@ -0,0 +1,120 @@ |
|||||
|
/*global suite, test*/ |
||||
|
|
||||
|
var assert = require("assert") |
||||
|
, after = require("../") |
||||
|
|
||||
|
test("exists", function () { |
||||
|
assert(typeof after === "function", "after is not a function") |
||||
|
}) |
||||
|
|
||||
|
test("after when called with 0 invokes", function (done) { |
||||
|
after(0, done) |
||||
|
}); |
||||
|
|
||||
|
test("after 1", function (done) { |
||||
|
var next = after(1, done) |
||||
|
next() |
||||
|
}) |
||||
|
|
||||
|
test("after 5", function (done) { |
||||
|
var next = after(5, done) |
||||
|
, i = 5 |
||||
|
|
||||
|
while (i--) { |
||||
|
next() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
test("manipulate count", function (done) { |
||||
|
var next = after(1, done) |
||||
|
, i = 5 |
||||
|
|
||||
|
next.count = i |
||||
|
while (i--) { |
||||
|
next() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
test("after terminates on error", function (done) { |
||||
|
var next = after(2, function(err) { |
||||
|
assert.equal(err.message, 'test'); |
||||
|
done(); |
||||
|
}) |
||||
|
next(new Error('test')) |
||||
|
next(new Error('test2')) |
||||
|
}) |
||||
|
|
||||
|
test('gee', function(done) { |
||||
|
done = after(2, done) |
||||
|
|
||||
|
function cb(err) { |
||||
|
assert.equal(err.message, 1); |
||||
|
done() |
||||
|
} |
||||
|
|
||||
|
var next = after(3, cb, function(err) { |
||||
|
assert.equal(err.message, 2) |
||||
|
done() |
||||
|
}); |
||||
|
|
||||
|
next() |
||||
|
next(new Error(1)) |
||||
|
next(new Error(2)) |
||||
|
}) |
||||
|
|
||||
|
test('eee', function(done) { |
||||
|
done = after(3, done) |
||||
|
|
||||
|
function cb(err) { |
||||
|
assert.equal(err.message, 1); |
||||
|
done() |
||||
|
} |
||||
|
|
||||
|
var next = after(3, cb, function(err) { |
||||
|
assert.equal(err.message, 2) |
||||
|
done() |
||||
|
}); |
||||
|
|
||||
|
next(new Error(1)) |
||||
|
next(new Error(2)) |
||||
|
next(new Error(2)) |
||||
|
}) |
||||
|
|
||||
|
test('gge', function(done) { |
||||
|
function cb(err) { |
||||
|
assert.equal(err.message, 1); |
||||
|
done() |
||||
|
} |
||||
|
|
||||
|
var next = after(3, cb, function(err) { |
||||
|
// should not happen
|
||||
|
assert.ok(false); |
||||
|
}); |
||||
|
|
||||
|
next() |
||||
|
next() |
||||
|
next(new Error(1)) |
||||
|
}) |
||||
|
|
||||
|
test('egg', function(done) { |
||||
|
function cb(err) { |
||||
|
assert.equal(err.message, 1); |
||||
|
done() |
||||
|
} |
||||
|
|
||||
|
var next = after(3, cb, function(err) { |
||||
|
// should not happen
|
||||
|
assert.ok(false); |
||||
|
}); |
||||
|
|
||||
|
next(new Error(1)) |
||||
|
next() |
||||
|
next() |
||||
|
}) |
||||
|
|
||||
|
test('throws on too many calls', function(done) { |
||||
|
var next = after(1, done); |
||||
|
next() |
||||
|
assert.throws(next, /after called too many times/); |
||||
|
}); |
||||
|
|
@ -0,0 +1,17 @@ |
|||||
|
lib-cov |
||||
|
lcov.info |
||||
|
*.seed |
||||
|
*.log |
||||
|
*.csv |
||||
|
*.dat |
||||
|
*.out |
||||
|
*.pid |
||||
|
*.gz |
||||
|
|
||||
|
pids |
||||
|
logs |
||||
|
results |
||||
|
build |
||||
|
.grunt |
||||
|
|
||||
|
node_modules |
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
REPORTER = dot |
||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/mocha \
|
||||
|
--reporter $(REPORTER) |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,17 @@ |
|||||
|
# How to |
||||
|
```javascript |
||||
|
var sliceBuffer = require('arraybuffer.slice'); |
||||
|
var ab = (new Int8Array(5)).buffer; |
||||
|
var sliced = sliceBuffer(ab, 1, 3); |
||||
|
sliced = sliceBuffer(ab, 1); |
||||
|
``` |
||||
|
|
||||
|
# Licence (MIT) |
||||
|
Copyright (C) 2013 Rase- |
||||
|
|
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,29 @@ |
|||||
|
/** |
||||
|
* An abstraction for slicing an arraybuffer even when |
||||
|
* ArrayBuffer.prototype.slice is not supported |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
module.exports = function(arraybuffer, start, end) { |
||||
|
var bytes = arraybuffer.byteLength; |
||||
|
start = start || 0; |
||||
|
end = end || bytes; |
||||
|
|
||||
|
if (arraybuffer.slice) { return arraybuffer.slice(start, end); } |
||||
|
|
||||
|
if (start < 0) { start += bytes; } |
||||
|
if (end < 0) { end += bytes; } |
||||
|
if (end > bytes) { end = bytes; } |
||||
|
|
||||
|
if (start >= bytes || start >= end || bytes === 0) { |
||||
|
return new ArrayBuffer(0); |
||||
|
} |
||||
|
|
||||
|
var abv = new Uint8Array(arraybuffer); |
||||
|
var result = new Uint8Array(end - start); |
||||
|
for (var i = start, ii = 0; i < end; i++, ii++) { |
||||
|
result[ii] = abv[i]; |
||||
|
} |
||||
|
return result.buffer; |
||||
|
}; |
@ -0,0 +1,72 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "arraybuffer.slice@0.0.6", |
||||
|
"scope": null, |
||||
|
"escapedName": "arraybuffer.slice", |
||||
|
"name": "arraybuffer.slice", |
||||
|
"rawSpec": "0.0.6", |
||||
|
"spec": "0.0.6", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser" |
||||
|
] |
||||
|
], |
||||
|
"_from": "arraybuffer.slice@0.0.6", |
||||
|
"_id": "arraybuffer.slice@0.0.6", |
||||
|
"_inCache": true, |
||||
|
"_location": "/arraybuffer.slice", |
||||
|
"_npmUser": { |
||||
|
"name": "rase-", |
||||
|
"email": "tonykovanen@hotmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.3.5", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "arraybuffer.slice@0.0.6", |
||||
|
"scope": null, |
||||
|
"escapedName": "arraybuffer.slice", |
||||
|
"name": "arraybuffer.slice", |
||||
|
"rawSpec": "0.0.6", |
||||
|
"spec": "0.0.6", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io-parser" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", |
||||
|
"_shasum": "f33b2159f0532a3f3107a272c0ccfbd1ad2979ca", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "arraybuffer.slice@0.0.6", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/rase-/arraybuffer.slice/issues" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Exports a function for slicing ArrayBuffers (no polyfilling)", |
||||
|
"devDependencies": { |
||||
|
"expect.js": "0.2.0", |
||||
|
"mocha": "1.17.1" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "f33b2159f0532a3f3107a272c0ccfbd1ad2979ca", |
||||
|
"tarball": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz" |
||||
|
}, |
||||
|
"homepage": "https://github.com/rase-/arraybuffer.slice", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "rase-", |
||||
|
"email": "tonykovanen@hotmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "arraybuffer.slice", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+ssh://git@github.com/rase-/arraybuffer.slice.git" |
||||
|
}, |
||||
|
"version": "0.0.6" |
||||
|
} |
@ -0,0 +1,227 @@ |
|||||
|
/* |
||||
|
* Test dependencies |
||||
|
*/ |
||||
|
|
||||
|
var sliceBuffer = require('../index.js'); |
||||
|
var expect = require('expect.js'); |
||||
|
|
||||
|
/** |
||||
|
* Tests |
||||
|
*/ |
||||
|
|
||||
|
describe('sliceBuffer', function() { |
||||
|
describe('using standard slice', function() { |
||||
|
it('should slice correctly with only start provided', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 3, ii = 0; i < abv.length; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with start and end provided', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 3, 8); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 3, ii = 0; i < 8; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative start', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = abv.length - 3, ii = 0; i < abv.length; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 0, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 0, ii = 0; i < abv.length - 3; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative start and end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, -6, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = abv.length - 6, ii = 0; i < abv.length - 3; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with equal start and end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 1, 1); |
||||
|
expect(sliced.byteLength).to.equal(0); |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly when end larger than buffer', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 0, 100); |
||||
|
expect(new Uint8Array(sliced)).to.eql(abv); |
||||
|
}); |
||||
|
|
||||
|
it('shoud slice correctly when start larger than end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
|
||||
|
var sliced = sliceBuffer(abv.buffer, 6, 5); |
||||
|
expect(sliced.byteLength).to.equal(0); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe('using fallback', function() { |
||||
|
it('should slice correctly with only start provided', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 3, ii = 0; i < abv.length; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with start and end provided', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 3, 8); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 3, ii = 0; i < 8; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative start', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
|
||||
|
var sliced = sliceBuffer(ab, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = abv.length - 3, ii = 0; i < abv.length; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 0, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 0, ii = 0; i < abv.length - 3; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with negative start and end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, -6, -3); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = abv.length - 6, ii = 0; i < abv.length - 3; i++, ii++) { |
||||
|
expect(abv[i]).to.equal(sabv[ii]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly with equal start and end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 1, 1); |
||||
|
expect(sliced.byteLength).to.equal(0); |
||||
|
}); |
||||
|
|
||||
|
it('should slice correctly when end larger than buffer', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 0, 100); |
||||
|
var sabv = new Uint8Array(sliced); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
expect(abv[i]).to.equal(sabv[i]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
it('shoud slice correctly when start larger than end', function() { |
||||
|
var abv = new Uint8Array(10); |
||||
|
for (var i = 0; i < abv.length; i++) { |
||||
|
abv[i] = i; |
||||
|
} |
||||
|
var ab = abv.buffer; |
||||
|
ab.slice = undefined; |
||||
|
|
||||
|
var sliced = sliceBuffer(ab, 6, 5); |
||||
|
expect(sliced.byteLength).to.equal(0); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1 @@ |
|||||
|
node_modules/ |
@ -0,0 +1,12 @@ |
|||||
|
|
||||
|
1.0.1 / 2014-02-17 |
||||
|
================== |
||||
|
|
||||
|
* go away decimal point |
||||
|
* history |
||||
|
|
||||
|
1.0.0 / 2014-02-17 |
||||
|
================== |
||||
|
|
||||
|
* add jitter option |
||||
|
* Initial commit |
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/mocha \
|
||||
|
--require should \
|
||||
|
--reporter dot \
|
||||
|
--bail |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,34 @@ |
|||||
|
# backo |
||||
|
|
||||
|
Simple exponential backoff because the others seem to have weird abstractions. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
``` |
||||
|
$ npm install backo |
||||
|
``` |
||||
|
|
||||
|
## Options |
||||
|
|
||||
|
- `min` initial timeout in milliseconds [100] |
||||
|
- `max` max timeout [10000] |
||||
|
- `jitter` [0] |
||||
|
- `factor` [2] |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
```js |
||||
|
var Backoff = require('backo'); |
||||
|
var backoff = new Backoff({ min: 100, max: 20000 }); |
||||
|
|
||||
|
setTimeout(function(){ |
||||
|
something.reconnect(); |
||||
|
}, backoff.duration()); |
||||
|
|
||||
|
// later when something works |
||||
|
backoff.reset() |
||||
|
``` |
||||
|
|
||||
|
# License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"name": "backo", |
||||
|
"repo": "segmentio/backo", |
||||
|
"dependencies": {}, |
||||
|
"version": "1.0.1", |
||||
|
"description": "simple backoff without the weird abstractions", |
||||
|
"keywords": ["backoff"], |
||||
|
"license": "MIT", |
||||
|
"scripts": ["index.js"], |
||||
|
"main": "index.js" |
||||
|
} |
@ -0,0 +1,85 @@ |
|||||
|
|
||||
|
/** |
||||
|
* Expose `Backoff`. |
||||
|
*/ |
||||
|
|
||||
|
module.exports = Backoff; |
||||
|
|
||||
|
/** |
||||
|
* Initialize backoff timer with `opts`. |
||||
|
* |
||||
|
* - `min` initial timeout in milliseconds [100] |
||||
|
* - `max` max timeout [10000] |
||||
|
* - `jitter` [0] |
||||
|
* - `factor` [2] |
||||
|
* |
||||
|
* @param {Object} opts |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
function Backoff(opts) { |
||||
|
opts = opts || {}; |
||||
|
this.ms = opts.min || 100; |
||||
|
this.max = opts.max || 10000; |
||||
|
this.factor = opts.factor || 2; |
||||
|
this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; |
||||
|
this.attempts = 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return the backoff duration. |
||||
|
* |
||||
|
* @return {Number} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Backoff.prototype.duration = function(){ |
||||
|
var ms = this.ms * Math.pow(this.factor, this.attempts++); |
||||
|
if (this.jitter) { |
||||
|
var rand = Math.random(); |
||||
|
var deviation = Math.floor(rand * this.jitter * ms); |
||||
|
ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; |
||||
|
} |
||||
|
return Math.min(ms, this.max) | 0; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Reset the number of attempts. |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Backoff.prototype.reset = function(){ |
||||
|
this.attempts = 0; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Set the minimum duration |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Backoff.prototype.setMin = function(min){ |
||||
|
this.ms = min; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Set the maximum duration |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Backoff.prototype.setMax = function(max){ |
||||
|
this.max = max; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Set the jitter |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Backoff.prototype.setJitter = function(jitter){ |
||||
|
this.jitter = jitter; |
||||
|
}; |
||||
|
|
@ -0,0 +1,78 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "backo2@1.0.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "backo2", |
||||
|
"name": "backo2", |
||||
|
"rawSpec": "1.0.2", |
||||
|
"spec": "1.0.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-client" |
||||
|
] |
||||
|
], |
||||
|
"_from": "backo2@1.0.2", |
||||
|
"_id": "backo2@1.0.2", |
||||
|
"_inCache": true, |
||||
|
"_location": "/backo2", |
||||
|
"_npmUser": { |
||||
|
"name": "mokesmokes", |
||||
|
"email": "mokesmokes@gmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.4.28", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "backo2@1.0.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "backo2", |
||||
|
"name": "backo2", |
||||
|
"rawSpec": "1.0.2", |
||||
|
"spec": "1.0.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/socket.io-client" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", |
||||
|
"_shasum": "31ab1ac8b129363463e35b3ebb69f4dfcfba7947", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "backo2@1.0.2", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-client", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/mokesmokes/backo/issues" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "simple backoff based on segmentio/backo", |
||||
|
"devDependencies": { |
||||
|
"mocha": "*", |
||||
|
"should": "*" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "31ab1ac8b129363463e35b3ebb69f4dfcfba7947", |
||||
|
"tarball": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz" |
||||
|
}, |
||||
|
"gitHead": "3e695bade7756fef2295e8883bf3570a06e5d9ec", |
||||
|
"homepage": "https://github.com/mokesmokes/backo", |
||||
|
"keywords": [ |
||||
|
"backoff" |
||||
|
], |
||||
|
"license": "MIT", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "mokesmokes", |
||||
|
"email": "mokesmokes@gmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "backo2", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/mokesmokes/backo.git" |
||||
|
}, |
||||
|
"scripts": {}, |
||||
|
"version": "1.0.2" |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
|
||||
|
var Backoff = require('..'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
describe('.duration()', function(){ |
||||
|
it('should increase the backoff', function(){ |
||||
|
var b = new Backoff; |
||||
|
|
||||
|
assert(100 == b.duration()); |
||||
|
assert(200 == b.duration()); |
||||
|
assert(400 == b.duration()); |
||||
|
assert(800 == b.duration()); |
||||
|
|
||||
|
b.reset(); |
||||
|
assert(100 == b.duration()); |
||||
|
assert(200 == b.duration()); |
||||
|
}) |
||||
|
}) |
@ -0,0 +1,3 @@ |
|||||
|
/node_modules/ |
||||
|
Gruntfile.js |
||||
|
/test/ |
@ -0,0 +1,19 @@ |
|||||
|
language: node_js |
||||
|
node_js: |
||||
|
- '0.12' |
||||
|
- iojs-1 |
||||
|
- iojs-2 |
||||
|
- iojs-3 |
||||
|
- '4.1' |
||||
|
before_script: |
||||
|
- npm install |
||||
|
before_install: npm install -g npm@'>=2.13.5' |
||||
|
deploy: |
||||
|
provider: npm |
||||
|
email: niklasvh@gmail.com |
||||
|
api_key: |
||||
|
secure: oHV9ArprTj5WOk7MP1UF7QMJ70huXw+y7xXb5wF4+V2H8Hyfa5TfE0DiOmqrube1WXTeH1FLgq54shp/sJWi47Hkg/GyeoB5NnsPhYEaJkaON9UG5blML+ODiNVsEnq/1kNBQ8e0+0JItMPLGySKyFmuZ3yflulXKS8O88mfINo= |
||||
|
on: |
||||
|
tags: true |
||||
|
branch: master |
||||
|
repo: niklasvh/base64-arraybuffer |
@ -0,0 +1,22 @@ |
|||||
|
Copyright (c) 2012 Niklas von Hertzen |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person |
||||
|
obtaining a copy of this software and associated documentation |
||||
|
files (the "Software"), to deal in the Software without |
||||
|
restriction, including without limitation the rights to use, |
||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the |
||||
|
Software is furnished to do so, subject to the following |
||||
|
conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be |
||||
|
included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,20 @@ |
|||||
|
# base64-arraybuffer |
||||
|
|
||||
|
[![Build Status](https://travis-ci.org/niklasvh/base64-arraybuffer.png)](https://travis-ci.org/niklasvh/base64-arraybuffer) |
||||
|
[![NPM Downloads](https://img.shields.io/npm/dm/base64-arraybuffer.svg)](https://www.npmjs.org/package/base64-arraybuffer) |
||||
|
[![NPM Version](https://img.shields.io/npm/v/base64-arraybuffer.svg)](https://www.npmjs.org/package/base64-arraybuffer) |
||||
|
|
||||
|
Encode/decode base64 data into ArrayBuffers |
||||
|
|
||||
|
## Getting Started |
||||
|
Install the module with: `npm install base64-arraybuffer` |
||||
|
|
||||
|
## API |
||||
|
The library encodes and decodes base64 to and from ArrayBuffers |
||||
|
|
||||
|
- __encode(buffer)__ - Encodes `ArrayBuffer` into base64 string |
||||
|
- __decode(str)__ - Decodes base64 string to `ArrayBuffer` |
||||
|
|
||||
|
## License |
||||
|
Copyright (c) 2012 Niklas von Hertzen |
||||
|
Licensed under the MIT license. |
@ -0,0 +1,67 @@ |
|||||
|
/* |
||||
|
* base64-arraybuffer |
||||
|
* https://github.com/niklasvh/base64-arraybuffer
|
||||
|
* |
||||
|
* Copyright (c) 2012 Niklas von Hertzen |
||||
|
* Licensed under the MIT license. |
||||
|
*/ |
||||
|
(function(){ |
||||
|
"use strict"; |
||||
|
|
||||
|
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||||
|
|
||||
|
// Use a lookup table to find the index.
|
||||
|
var lookup = new Uint8Array(256); |
||||
|
for (var i = 0; i < chars.length; i++) { |
||||
|
lookup[chars.charCodeAt(i)] = i; |
||||
|
} |
||||
|
|
||||
|
exports.encode = function(arraybuffer) { |
||||
|
var bytes = new Uint8Array(arraybuffer), |
||||
|
i, len = bytes.length, base64 = ""; |
||||
|
|
||||
|
for (i = 0; i < len; i+=3) { |
||||
|
base64 += chars[bytes[i] >> 2]; |
||||
|
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; |
||||
|
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; |
||||
|
base64 += chars[bytes[i + 2] & 63]; |
||||
|
} |
||||
|
|
||||
|
if ((len % 3) === 2) { |
||||
|
base64 = base64.substring(0, base64.length - 1) + "="; |
||||
|
} else if (len % 3 === 1) { |
||||
|
base64 = base64.substring(0, base64.length - 2) + "=="; |
||||
|
} |
||||
|
|
||||
|
return base64; |
||||
|
}; |
||||
|
|
||||
|
exports.decode = function(base64) { |
||||
|
var bufferLength = base64.length * 0.75, |
||||
|
len = base64.length, i, p = 0, |
||||
|
encoded1, encoded2, encoded3, encoded4; |
||||
|
|
||||
|
if (base64[base64.length - 1] === "=") { |
||||
|
bufferLength--; |
||||
|
if (base64[base64.length - 2] === "=") { |
||||
|
bufferLength--; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var arraybuffer = new ArrayBuffer(bufferLength), |
||||
|
bytes = new Uint8Array(arraybuffer); |
||||
|
|
||||
|
for (i = 0; i < len; i+=4) { |
||||
|
encoded1 = lookup[base64.charCodeAt(i)]; |
||||
|
encoded2 = lookup[base64.charCodeAt(i+1)]; |
||||
|
encoded3 = lookup[base64.charCodeAt(i+2)]; |
||||
|
encoded4 = lookup[base64.charCodeAt(i+3)]; |
||||
|
|
||||
|
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); |
||||
|
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); |
||||
|
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); |
||||
|
} |
||||
|
|
||||
|
return arraybuffer; |
||||
|
}; |
||||
|
})(); |
@ -0,0 +1,96 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "base64-arraybuffer@0.1.5", |
||||
|
"scope": null, |
||||
|
"escapedName": "base64-arraybuffer", |
||||
|
"name": "base64-arraybuffer", |
||||
|
"rawSpec": "0.1.5", |
||||
|
"spec": "0.1.5", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser" |
||||
|
] |
||||
|
], |
||||
|
"_from": "base64-arraybuffer@0.1.5", |
||||
|
"_id": "base64-arraybuffer@0.1.5", |
||||
|
"_inCache": true, |
||||
|
"_location": "/base64-arraybuffer", |
||||
|
"_nodeVersion": "2.5.0", |
||||
|
"_npmUser": { |
||||
|
"name": "niklasvh", |
||||
|
"email": "niklasvh@gmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "3.4.0", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "base64-arraybuffer@0.1.5", |
||||
|
"scope": null, |
||||
|
"escapedName": "base64-arraybuffer", |
||||
|
"name": "base64-arraybuffer", |
||||
|
"rawSpec": "0.1.5", |
||||
|
"spec": "0.1.5", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io-parser" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", |
||||
|
"_shasum": "73926771923b5a19747ad666aa5cd4bf9c6e9ce8", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "base64-arraybuffer@0.1.5", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser", |
||||
|
"author": { |
||||
|
"name": "Niklas von Hertzen", |
||||
|
"email": "niklasvh@gmail.com", |
||||
|
"url": "http://hertzen.com" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/niklasvh/base64-arraybuffer/issues" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Encode/decode base64 data into ArrayBuffers", |
||||
|
"devDependencies": { |
||||
|
"grunt": "^0.4.5", |
||||
|
"grunt-cli": "^0.1.13", |
||||
|
"grunt-contrib-jshint": "^0.11.2", |
||||
|
"grunt-contrib-nodeunit": "^0.4.1", |
||||
|
"grunt-contrib-watch": "^0.6.1" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "73926771923b5a19747ad666aa5cd4bf9c6e9ce8", |
||||
|
"tarball": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 0.6.0" |
||||
|
}, |
||||
|
"gitHead": "e9457ccb7b140f5ae54a2880c8e9b967ffb03a7d", |
||||
|
"homepage": "https://github.com/niklasvh/base64-arraybuffer", |
||||
|
"keywords": [], |
||||
|
"licenses": [ |
||||
|
{ |
||||
|
"type": "MIT", |
||||
|
"url": "https://github.com/niklasvh/base64-arraybuffer/blob/master/LICENSE-MIT" |
||||
|
} |
||||
|
], |
||||
|
"main": "lib/base64-arraybuffer", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "niklasvh", |
||||
|
"email": "niklasvh@gmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "base64-arraybuffer", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/niklasvh/base64-arraybuffer.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "grunt nodeunit" |
||||
|
}, |
||||
|
"version": "0.1.5" |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
support |
||||
|
test |
||||
|
examples |
@ -0,0 +1,22 @@ |
|||||
|
(The MIT License) |
||||
|
|
||||
|
Copyright (c) 2012-2016 Kristian Faeldt <faeldt_kristian@cyberagent.co.jp> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining |
||||
|
a copy of this software and associated documentation files (the |
||||
|
'Software'), to deal in the Software without restriction, including |
||||
|
without limitation the rights to use, copy, modify, merge, publish, |
||||
|
distribute, sublicense, and/or sell copies of the Software, and to |
||||
|
permit persons to whom the Software is furnished to do so, subject to |
||||
|
the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be |
||||
|
included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, |
||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,18 @@ |
|||||
|
base64id |
||||
|
======== |
||||
|
|
||||
|
Node.js module that generates a base64 id. |
||||
|
|
||||
|
Uses crypto.randomBytes when available, falls back to unsafe methods for node.js <= 0.4. |
||||
|
|
||||
|
To increase performance, random bytes are buffered to minimize the number of synchronous calls to crypto.randomBytes. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
$ npm install base64id |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
var base64id = require('base64id'); |
||||
|
|
||||
|
var id = base64id.generateId(); |
@ -0,0 +1,103 @@ |
|||||
|
/*! |
||||
|
* base64id v0.1.0 |
||||
|
*/ |
||||
|
|
||||
|
/** |
||||
|
* Module dependencies |
||||
|
*/ |
||||
|
|
||||
|
var crypto = require('crypto'); |
||||
|
|
||||
|
/** |
||||
|
* Constructor |
||||
|
*/ |
||||
|
|
||||
|
var Base64Id = function() { }; |
||||
|
|
||||
|
/** |
||||
|
* Get random bytes |
||||
|
* |
||||
|
* Uses a buffer if available, falls back to crypto.randomBytes |
||||
|
*/ |
||||
|
|
||||
|
Base64Id.prototype.getRandomBytes = function(bytes) { |
||||
|
|
||||
|
var BUFFER_SIZE = 4096 |
||||
|
var self = this; |
||||
|
|
||||
|
bytes = bytes || 12; |
||||
|
|
||||
|
if (bytes > BUFFER_SIZE) { |
||||
|
return crypto.randomBytes(bytes); |
||||
|
} |
||||
|
|
||||
|
var bytesInBuffer = parseInt(BUFFER_SIZE/bytes); |
||||
|
var threshold = parseInt(bytesInBuffer*0.85); |
||||
|
|
||||
|
if (!threshold) { |
||||
|
return crypto.randomBytes(bytes); |
||||
|
} |
||||
|
|
||||
|
if (this.bytesBufferIndex == null) { |
||||
|
this.bytesBufferIndex = -1; |
||||
|
} |
||||
|
|
||||
|
if (this.bytesBufferIndex == bytesInBuffer) { |
||||
|
this.bytesBuffer = null; |
||||
|
this.bytesBufferIndex = -1; |
||||
|
} |
||||
|
|
||||
|
// No buffered bytes available or index above threshold
|
||||
|
if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) { |
||||
|
|
||||
|
if (!this.isGeneratingBytes) { |
||||
|
this.isGeneratingBytes = true; |
||||
|
crypto.randomBytes(BUFFER_SIZE, function(err, bytes) { |
||||
|
self.bytesBuffer = bytes; |
||||
|
self.bytesBufferIndex = 0; |
||||
|
self.isGeneratingBytes = false; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// Fall back to sync call when no buffered bytes are available
|
||||
|
if (this.bytesBufferIndex == -1) { |
||||
|
return crypto.randomBytes(bytes); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1)); |
||||
|
this.bytesBufferIndex++; |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates a base64 id |
||||
|
* |
||||
|
* (Original version from socket.io <http://socket.io>)
|
||||
|
*/ |
||||
|
|
||||
|
Base64Id.prototype.generateId = function () { |
||||
|
var rand = new Buffer(15); // multiple of 3 for base64
|
||||
|
if (!rand.writeInt32BE) { |
||||
|
return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString() |
||||
|
+ Math.abs(Math.random() * Math.random() * Date.now() | 0).toString(); |
||||
|
} |
||||
|
this.sequenceNumber = (this.sequenceNumber + 1) | 0; |
||||
|
rand.writeInt32BE(this.sequenceNumber, 11); |
||||
|
if (crypto.randomBytes) { |
||||
|
this.getRandomBytes(12).copy(rand); |
||||
|
} else { |
||||
|
// not secure for node 0.4
|
||||
|
[0, 4, 8].forEach(function(i) { |
||||
|
rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i); |
||||
|
}); |
||||
|
} |
||||
|
return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-'); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Export |
||||
|
*/ |
||||
|
|
||||
|
exports = module.exports = new Base64Id(); |
@ -0,0 +1,89 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "base64id@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "base64id", |
||||
|
"name": "base64id", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io" |
||||
|
] |
||||
|
], |
||||
|
"_from": "base64id@1.0.0", |
||||
|
"_id": "base64id@1.0.0", |
||||
|
"_inCache": true, |
||||
|
"_location": "/base64id", |
||||
|
"_nodeVersion": "4.4.7", |
||||
|
"_npmOperationalInternal": { |
||||
|
"host": "packages-18-east.internal.npmjs.com", |
||||
|
"tmp": "tmp/base64id-1.0.0.tgz_1480551701495_0.042360062478110194" |
||||
|
}, |
||||
|
"_npmUser": { |
||||
|
"name": "darrachequesne", |
||||
|
"email": "damien.arrachequesne@gmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "2.15.8", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "base64id@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "base64id", |
||||
|
"name": "base64id", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", |
||||
|
"_shasum": "47688cb99bb6804f0e06d3e763b1c32e57d8e6b6", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "base64id@1.0.0", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io", |
||||
|
"author": { |
||||
|
"name": "Kristian Faeldt", |
||||
|
"email": "faeldt_kristian@cyberagent.co.jp" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/faeldt/base64id/issues" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Generates a base64 id", |
||||
|
"devDependencies": {}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "47688cb99bb6804f0e06d3e763b1c32e57d8e6b6", |
||||
|
"tarball": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">= 0.4.0" |
||||
|
}, |
||||
|
"gitHead": "3c846f0818ff88b683ad39fde2f8e015ce0f9807", |
||||
|
"homepage": "https://github.com/faeldt/base64id#readme", |
||||
|
"license": "MIT", |
||||
|
"main": "./lib/base64id.js", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "darrachequesne", |
||||
|
"email": "damien.arrachequesne@gmail.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "faeldt_kristian", |
||||
|
"email": "kristian.faeldt@gmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "base64id", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/faeldt/base64id.git" |
||||
|
}, |
||||
|
"scripts": {}, |
||||
|
"version": "1.0.0" |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
support |
||||
|
test |
||||
|
examples |
||||
|
*.sock |
@ -0,0 +1,15 @@ |
|||||
|
|
||||
|
1.0.0 / 2013-02-03 |
||||
|
================== |
||||
|
|
||||
|
* Stop using the removed magic __stack global getter |
||||
|
|
||||
|
0.1.0 / 2012-10-04 |
||||
|
================== |
||||
|
|
||||
|
* add throwing of AssertionError for test frameworks etc |
||||
|
|
||||
|
0.0.1 / 2010-01-03 |
||||
|
================== |
||||
|
|
||||
|
* Initial release |
@ -0,0 +1,5 @@ |
|||||
|
|
||||
|
test: |
||||
|
@echo "populate me" |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,61 @@ |
|||||
|
|
||||
|
# better-assert |
||||
|
|
||||
|
Better c-style assertions using [callsite](https://github.com/visionmedia/callsite) for |
||||
|
self-documenting failure messages. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
$ npm install better-assert |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
By default assertions are enabled, however the __NO_ASSERT__ environment variable |
||||
|
will deactivate them when truthy. |
||||
|
|
||||
|
```js |
||||
|
var assert = require('better-assert'); |
||||
|
|
||||
|
test(); |
||||
|
|
||||
|
function test() { |
||||
|
var user = { name: 'tobi' }; |
||||
|
assert('tobi' == user.name); |
||||
|
assert('number' == typeof user.age); |
||||
|
} |
||||
|
|
||||
|
AssertionError: 'number' == typeof user.age |
||||
|
at test (/Users/tj/projects/better-assert/example.js:9:3) |
||||
|
at Object.<anonymous> (/Users/tj/projects/better-assert/example.js:4:1) |
||||
|
at Module._compile (module.js:449:26) |
||||
|
at Object.Module._extensions..js (module.js:467:10) |
||||
|
at Module.load (module.js:356:32) |
||||
|
at Function.Module._load (module.js:312:12) |
||||
|
at Module.runMain (module.js:492:10) |
||||
|
at process.startup.processNextTick.process._tickCallback (node.js:244:9) |
||||
|
``` |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
(The MIT License) |
||||
|
|
||||
|
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining |
||||
|
a copy of this software and associated documentation files (the |
||||
|
'Software'), to deal in the Software without restriction, including |
||||
|
without limitation the rights to use, copy, modify, merge, publish, |
||||
|
distribute, sublicense, and/or sell copies of the Software, and to |
||||
|
permit persons to whom the Software is furnished to do so, subject to |
||||
|
the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be |
||||
|
included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, |
||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
var assert = require('./'); |
||||
|
|
||||
|
test(); |
||||
|
|
||||
|
function test() { |
||||
|
var user = { name: 'tobi' }; |
||||
|
assert('tobi' == user.name); |
||||
|
assert('number' == typeof user.age); |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
/** |
||||
|
* Module dependencies. |
||||
|
*/ |
||||
|
|
||||
|
var AssertionError = require('assert').AssertionError |
||||
|
, callsite = require('callsite') |
||||
|
, fs = require('fs') |
||||
|
|
||||
|
/** |
||||
|
* Expose `assert`. |
||||
|
*/ |
||||
|
|
||||
|
module.exports = process.env.NO_ASSERT |
||||
|
? function(){} |
||||
|
: assert; |
||||
|
|
||||
|
/** |
||||
|
* Assert the given `expr`. |
||||
|
*/ |
||||
|
|
||||
|
function assert(expr) { |
||||
|
if (expr) return; |
||||
|
|
||||
|
var stack = callsite(); |
||||
|
var call = stack[1]; |
||||
|
var file = call.getFileName(); |
||||
|
var lineno = call.getLineNumber(); |
||||
|
var src = fs.readFileSync(file, 'utf8'); |
||||
|
var line = src.split('\n')[lineno-1]; |
||||
|
var src = line.match(/assert\((.*)\)/)[1]; |
||||
|
|
||||
|
var err = new AssertionError({ |
||||
|
message: src, |
||||
|
stackStartFunction: stack[0].getFunction() |
||||
|
}); |
||||
|
|
||||
|
throw err; |
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "better-assert@~1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "better-assert", |
||||
|
"name": "better-assert", |
||||
|
"rawSpec": "~1.0.0", |
||||
|
"spec": ">=1.0.0 <1.1.0", |
||||
|
"type": "range" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/parsejson" |
||||
|
] |
||||
|
], |
||||
|
"_from": "better-assert@>=1.0.0 <1.1.0", |
||||
|
"_id": "better-assert@1.0.2", |
||||
|
"_inCache": true, |
||||
|
"_location": "/better-assert", |
||||
|
"_npmUser": { |
||||
|
"name": "tony_ado", |
||||
|
"email": "coolhzb@163.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.4.9", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "better-assert@~1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "better-assert", |
||||
|
"name": "better-assert", |
||||
|
"rawSpec": "~1.0.0", |
||||
|
"spec": ">=1.0.0 <1.1.0", |
||||
|
"type": "range" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/parsejson", |
||||
|
"/parseqs", |
||||
|
"/parseuri" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", |
||||
|
"_shasum": "40866b9e1b9e0b55b481894311e68faffaebc522", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "better-assert@~1.0.0", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/parsejson", |
||||
|
"author": { |
||||
|
"name": "TJ Holowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/visionmedia/better-assert/issues" |
||||
|
}, |
||||
|
"contributors": [ |
||||
|
{ |
||||
|
"name": "TonyHe", |
||||
|
"email": "coolhzb@163.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "ForbesLindesay" |
||||
|
} |
||||
|
], |
||||
|
"dependencies": { |
||||
|
"callsite": "1.0.0" |
||||
|
}, |
||||
|
"description": "Better assertions for node, reporting the expr, filename, lineno etc", |
||||
|
"devDependencies": {}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "40866b9e1b9e0b55b481894311e68faffaebc522", |
||||
|
"tarball": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": "*" |
||||
|
}, |
||||
|
"homepage": "https://github.com/visionmedia/better-assert", |
||||
|
"keywords": [ |
||||
|
"assert", |
||||
|
"stack", |
||||
|
"trace", |
||||
|
"debug" |
||||
|
], |
||||
|
"main": "index", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "tjholowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "tony_ado", |
||||
|
"email": "coolhzb@163.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "better-assert", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/visionmedia/better-assert.git" |
||||
|
}, |
||||
|
"version": "1.0.2" |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
node_modules |
||||
|
blob.js |
@ -0,0 +1,14 @@ |
|||||
|
ui: mocha-bdd |
||||
|
browsers: |
||||
|
- name: chrome |
||||
|
version: 8..latest |
||||
|
- name: firefox |
||||
|
version: 7..latest |
||||
|
- name: safari |
||||
|
version: 6..latest |
||||
|
- name: opera |
||||
|
version: 12.1..latest |
||||
|
- name: ie |
||||
|
version: 10..latest |
||||
|
- name: android |
||||
|
version: latest |
@ -0,0 +1,14 @@ |
|||||
|
REPORTER = dot |
||||
|
|
||||
|
build: blob.js |
||||
|
|
||||
|
blob.js: |
||||
|
@./node_modules/.bin/browserify --standalone blob index.js > blob.js |
||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/zuul -- test/index.js |
||||
|
|
||||
|
clean: |
||||
|
rm blob.js |
||||
|
|
||||
|
.PHONY: test blob.js |
@ -0,0 +1,14 @@ |
|||||
|
Blob |
||||
|
==== |
||||
|
|
||||
|
A module that exports a constructor that uses window.Blob when available, and a BlobBuilder with any vendor prefix in other cases. If neither is available, it exports undefined. |
||||
|
|
||||
|
Usage: |
||||
|
|
||||
|
```javascript |
||||
|
var Blob = require('blob'); |
||||
|
var b = new Blob(['hi', 'constructing', 'a', 'blob']); |
||||
|
``` |
||||
|
|
||||
|
## Licence |
||||
|
MIT |
@ -0,0 +1,96 @@ |
|||||
|
/** |
||||
|
* Create a blob builder even when vendor prefixes exist |
||||
|
*/ |
||||
|
|
||||
|
var BlobBuilder = global.BlobBuilder |
||||
|
|| global.WebKitBlobBuilder |
||||
|
|| global.MSBlobBuilder |
||||
|
|| global.MozBlobBuilder; |
||||
|
|
||||
|
/** |
||||
|
* Check if Blob constructor is supported |
||||
|
*/ |
||||
|
|
||||
|
var blobSupported = (function() { |
||||
|
try { |
||||
|
var a = new Blob(['hi']); |
||||
|
return a.size === 2; |
||||
|
} catch(e) { |
||||
|
return false; |
||||
|
} |
||||
|
})(); |
||||
|
|
||||
|
/** |
||||
|
* Check if Blob constructor supports ArrayBufferViews |
||||
|
* Fails in Safari 6, so we need to map to ArrayBuffers there. |
||||
|
*/ |
||||
|
|
||||
|
var blobSupportsArrayBufferView = blobSupported && (function() { |
||||
|
try { |
||||
|
var b = new Blob([new Uint8Array([1,2])]); |
||||
|
return b.size === 2; |
||||
|
} catch(e) { |
||||
|
return false; |
||||
|
} |
||||
|
})(); |
||||
|
|
||||
|
/** |
||||
|
* Check if BlobBuilder is supported |
||||
|
*/ |
||||
|
|
||||
|
var blobBuilderSupported = BlobBuilder |
||||
|
&& BlobBuilder.prototype.append |
||||
|
&& BlobBuilder.prototype.getBlob; |
||||
|
|
||||
|
/** |
||||
|
* Helper function that maps ArrayBufferViews to ArrayBuffers |
||||
|
* Used by BlobBuilder constructor and old browsers that didn't |
||||
|
* support it in the Blob constructor. |
||||
|
*/ |
||||
|
|
||||
|
function mapArrayBufferViews(ary) { |
||||
|
for (var i = 0; i < ary.length; i++) { |
||||
|
var chunk = ary[i]; |
||||
|
if (chunk.buffer instanceof ArrayBuffer) { |
||||
|
var buf = chunk.buffer; |
||||
|
|
||||
|
// if this is a subarray, make a copy so we only
|
||||
|
// include the subarray region from the underlying buffer
|
||||
|
if (chunk.byteLength !== buf.byteLength) { |
||||
|
var copy = new Uint8Array(chunk.byteLength); |
||||
|
copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); |
||||
|
buf = copy.buffer; |
||||
|
} |
||||
|
|
||||
|
ary[i] = buf; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function BlobBuilderConstructor(ary, options) { |
||||
|
options = options || {}; |
||||
|
|
||||
|
var bb = new BlobBuilder(); |
||||
|
mapArrayBufferViews(ary); |
||||
|
|
||||
|
for (var i = 0; i < ary.length; i++) { |
||||
|
bb.append(ary[i]); |
||||
|
} |
||||
|
|
||||
|
return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); |
||||
|
}; |
||||
|
|
||||
|
function BlobConstructor(ary, options) { |
||||
|
mapArrayBufferViews(ary); |
||||
|
return new Blob(ary, options || {}); |
||||
|
}; |
||||
|
|
||||
|
module.exports = (function() { |
||||
|
if (blobSupported) { |
||||
|
return blobSupportsArrayBufferView ? global.Blob : BlobConstructor; |
||||
|
} else if (blobBuilderSupported) { |
||||
|
return BlobBuilderConstructor; |
||||
|
} else { |
||||
|
return undefined; |
||||
|
} |
||||
|
})(); |
@ -0,0 +1,77 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "blob@0.0.4", |
||||
|
"scope": null, |
||||
|
"escapedName": "blob", |
||||
|
"name": "blob", |
||||
|
"rawSpec": "0.0.4", |
||||
|
"spec": "0.0.4", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser" |
||||
|
] |
||||
|
], |
||||
|
"_from": "blob@0.0.4", |
||||
|
"_id": "blob@0.0.4", |
||||
|
"_inCache": true, |
||||
|
"_location": "/blob", |
||||
|
"_npmUser": { |
||||
|
"name": "rase-", |
||||
|
"email": "tonykovanen@hotmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.4.6", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "blob@0.0.4", |
||||
|
"scope": null, |
||||
|
"escapedName": "blob", |
||||
|
"name": "blob", |
||||
|
"rawSpec": "0.0.4", |
||||
|
"spec": "0.0.4", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io-parser" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", |
||||
|
"_shasum": "bcf13052ca54463f30f9fc7e95b9a47630a94921", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "blob@0.0.4", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-parser", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/rase-/blob/issues" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Abstracts out Blob and uses BlobBulder in cases where it is supported with any vendor prefix.", |
||||
|
"devDependencies": { |
||||
|
"browserify": "3.30.1", |
||||
|
"expect.js": "0.2.0", |
||||
|
"mocha": "1.17.1", |
||||
|
"zuul": "1.5.4" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "bcf13052ca54463f30f9fc7e95b9a47630a94921", |
||||
|
"tarball": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz" |
||||
|
}, |
||||
|
"homepage": "https://github.com/rase-/blob", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "rase-", |
||||
|
"email": "tonykovanen@hotmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "blob", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+ssh://git@github.com/rase-/blob.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "make test" |
||||
|
}, |
||||
|
"version": "0.0.4" |
||||
|
} |
@ -0,0 +1,94 @@ |
|||||
|
var Blob = require('../'); |
||||
|
var expect = require('expect.js'); |
||||
|
|
||||
|
describe('blob', function() { |
||||
|
if (!Blob) { |
||||
|
it('should not have a blob or a blob builder in the global namespace, or blob should not be a constructor function if the module exports false', function() { |
||||
|
try { |
||||
|
var ab = (new Uint8Array(5)).buffer; |
||||
|
global.Blob([ab]); |
||||
|
expect().fail('Blob shouldn\'t be constructable'); |
||||
|
} catch (e) {} |
||||
|
|
||||
|
var BlobBuilder = global.BlobBuilder |
||||
|
|| global.WebKitBlobBuilder |
||||
|
|| global.MSBlobBuilder |
||||
|
|| global.MozBlobBuilder; |
||||
|
expect(BlobBuilder).to.be(undefined); |
||||
|
}); |
||||
|
} else { |
||||
|
it('should encode a proper sized blob when given a string argument', function() { |
||||
|
var b = new Blob(['hi']); |
||||
|
expect(b.size).to.be(2); |
||||
|
}); |
||||
|
|
||||
|
it('should encode a blob with proper size when given two strings as arguments', function() { |
||||
|
var b = new Blob(['hi', 'hello']); |
||||
|
expect(b.size).to.be(7); |
||||
|
}); |
||||
|
|
||||
|
it('should encode arraybuffers with right content', function(done) { |
||||
|
var ary = new Uint8Array(5); |
||||
|
for (var i = 0; i < 5; i++) ary[i] = i; |
||||
|
var b = new Blob([ary.buffer]); |
||||
|
var fr = new FileReader(); |
||||
|
fr.onload = function() { |
||||
|
var newAry = new Uint8Array(this.result); |
||||
|
for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); |
||||
|
done(); |
||||
|
}; |
||||
|
fr.readAsArrayBuffer(b); |
||||
|
}); |
||||
|
|
||||
|
it('should encode typed arrays with right content', function(done) { |
||||
|
var ary = new Uint8Array(5); |
||||
|
for (var i = 0; i < 5; i++) ary[i] = i; |
||||
|
var b = new Blob([ary]); |
||||
|
var fr = new FileReader(); |
||||
|
fr.onload = function() { |
||||
|
var newAry = new Uint8Array(this.result); |
||||
|
for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); |
||||
|
done(); |
||||
|
}; |
||||
|
fr.readAsArrayBuffer(b); |
||||
|
}); |
||||
|
|
||||
|
it('should encode sliced typed arrays with right content', function(done) { |
||||
|
var ary = new Uint8Array(5); |
||||
|
for (var i = 0; i < 5; i++) ary[i] = i; |
||||
|
var b = new Blob([ary.subarray(2)]); |
||||
|
var fr = new FileReader(); |
||||
|
fr.onload = function() { |
||||
|
var newAry = new Uint8Array(this.result); |
||||
|
for (var i = 0; i < 3; i++) expect(newAry[i]).to.be(i + 2); |
||||
|
done(); |
||||
|
}; |
||||
|
fr.readAsArrayBuffer(b); |
||||
|
}); |
||||
|
|
||||
|
it('should encode with blobs', function(done) { |
||||
|
var ary = new Uint8Array(5); |
||||
|
for (var i = 0; i < 5; i++) ary[i] = i; |
||||
|
var b = new Blob([new Blob([ary.buffer])]); |
||||
|
var fr = new FileReader(); |
||||
|
fr.onload = function() { |
||||
|
var newAry = new Uint8Array(this.result); |
||||
|
for (var i = 0; i < 5; i++) expect(newAry[i]).to.be(i); |
||||
|
done(); |
||||
|
}; |
||||
|
fr.readAsArrayBuffer(b); |
||||
|
}); |
||||
|
|
||||
|
it('should enode mixed contents to right size', function() { |
||||
|
var ary = new Uint8Array(5); |
||||
|
for (var i = 0; i < 5; i++) ary[i] = i; |
||||
|
var b = new Blob([ary.buffer, 'hello']); |
||||
|
expect(b.size).to.be(10); |
||||
|
}); |
||||
|
|
||||
|
it('should accept mime type', function() { |
||||
|
var b = new Blob(['hi', 'hello'], { type: 'text/html' }); |
||||
|
expect(b.type).to.be('text/html'); |
||||
|
}); |
||||
|
} |
||||
|
}); |
@ -0,0 +1,4 @@ |
|||||
|
support |
||||
|
test |
||||
|
examples |
||||
|
*.sock |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
1.0.0 / 2013-01-24 |
||||
|
================== |
||||
|
|
||||
|
* remove lame magical getters |
||||
|
|
||||
|
0.0.1 / 2010-01-03 |
||||
|
================== |
||||
|
|
||||
|
* Initial release |
@ -0,0 +1,6 @@ |
|||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/mocha \
|
||||
|
--require should |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,44 @@ |
|||||
|
# callstack |
||||
|
|
||||
|
Access to v8's "raw" `CallSite`s. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
$ npm install callsite |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
```js |
||||
|
var stack = require('callsite'); |
||||
|
|
||||
|
foo(); |
||||
|
|
||||
|
function foo() { |
||||
|
bar(); |
||||
|
} |
||||
|
|
||||
|
function bar() { |
||||
|
baz(); |
||||
|
} |
||||
|
|
||||
|
function baz() { |
||||
|
console.log(); |
||||
|
stack().forEach(function(site){ |
||||
|
console.log(' \033[36m%s\033[90m in %s:%d\033[0m' |
||||
|
, site.getFunctionName() || 'anonymous' |
||||
|
, site.getFileName() |
||||
|
, site.getLineNumber()); |
||||
|
}); |
||||
|
console.log(); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Why? |
||||
|
|
||||
|
Because you can do weird, stupid, clever, wacky things such as: |
||||
|
|
||||
|
- [better-assert](https://github.com/visionmedia/better-assert) |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
module.exports = function(){ |
||||
|
var orig = Error.prepareStackTrace; |
||||
|
Error.prepareStackTrace = function(_, stack){ return stack; }; |
||||
|
var err = new Error; |
||||
|
Error.captureStackTrace(err, arguments.callee); |
||||
|
var stack = err.stack; |
||||
|
Error.prepareStackTrace = orig; |
||||
|
return stack; |
||||
|
}; |
@ -0,0 +1,77 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "callsite@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "callsite", |
||||
|
"name": "callsite", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/better-assert" |
||||
|
] |
||||
|
], |
||||
|
"_from": "callsite@1.0.0", |
||||
|
"_id": "callsite@1.0.0", |
||||
|
"_inCache": true, |
||||
|
"_location": "/callsite", |
||||
|
"_npmUser": { |
||||
|
"name": "tjholowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
}, |
||||
|
"_npmVersion": "1.2.2", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "callsite@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "callsite", |
||||
|
"name": "callsite", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/better-assert" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", |
||||
|
"_shasum": "280398e5d664bd74038b6f0905153e6e8af1bc20", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "callsite@1.0.0", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/better-assert", |
||||
|
"author": { |
||||
|
"name": "TJ Holowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "access to v8's CallSites", |
||||
|
"devDependencies": { |
||||
|
"mocha": "*", |
||||
|
"should": "*" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "280398e5d664bd74038b6f0905153e6e8af1bc20", |
||||
|
"tarball": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": "*" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"stack", |
||||
|
"trace", |
||||
|
"line" |
||||
|
], |
||||
|
"main": "index", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "tjholowaychuk", |
||||
|
"email": "tj@vision-media.ca" |
||||
|
} |
||||
|
], |
||||
|
"name": "callsite", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"version": "1.0.0" |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
support |
||||
|
test |
||||
|
examples |
||||
|
*.sock |
@ -0,0 +1,13 @@ |
|||||
|
|
||||
|
1.0.0 / 2014-05-27 |
||||
|
================== |
||||
|
|
||||
|
* index: use slice ref (#7, @viatropos) |
||||
|
* package: rename package to "component-bind" |
||||
|
* package: add "repository" field (#6, @repoify) |
||||
|
* package: add "component" section |
||||
|
|
||||
|
0.0.1 / 2010-01-03 |
||||
|
================== |
||||
|
|
||||
|
* Initial release |
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/mocha \
|
||||
|
--require should \
|
||||
|
--reporter spec |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,64 @@ |
|||||
|
# bind |
||||
|
|
||||
|
Function binding utility. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
``` |
||||
|
$ component install component/bind |
||||
|
``` |
||||
|
|
||||
|
## API |
||||
|
|
||||
|
- [bind(obj, fn)](#bindobj-fn) |
||||
|
- [bind(obj, fn, ...)](#bindobj-fn-) |
||||
|
- [bind(obj, name)](#bindobj-name) |
||||
|
<a name=""></a> |
||||
|
|
||||
|
<a name="bindobj-fn"></a> |
||||
|
### bind(obj, fn) |
||||
|
should bind the function to the given object. |
||||
|
|
||||
|
```js |
||||
|
var tobi = { name: 'tobi' }; |
||||
|
|
||||
|
function name() { |
||||
|
return this.name; |
||||
|
} |
||||
|
|
||||
|
var fn = bind(tobi, name); |
||||
|
fn().should.equal('tobi'); |
||||
|
``` |
||||
|
|
||||
|
<a name="bindobj-fn-"></a> |
||||
|
### bind(obj, fn, ...) |
||||
|
should curry the remaining arguments. |
||||
|
|
||||
|
```js |
||||
|
function add(a, b) { |
||||
|
return a + b; |
||||
|
} |
||||
|
|
||||
|
bind(null, add)(1, 2).should.equal(3); |
||||
|
bind(null, add, 1)(2).should.equal(3); |
||||
|
bind(null, add, 1, 2)().should.equal(3); |
||||
|
``` |
||||
|
|
||||
|
<a name="bindobj-name"></a> |
||||
|
### bind(obj, name) |
||||
|
should bind the method of the given name. |
||||
|
|
||||
|
```js |
||||
|
var tobi = { name: 'tobi' }; |
||||
|
|
||||
|
tobi.getName = function() { |
||||
|
return this.name; |
||||
|
}; |
||||
|
|
||||
|
var fn = bind(tobi, 'getName'); |
||||
|
fn().should.equal('tobi'); |
||||
|
``` |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"name": "bind", |
||||
|
"version": "1.0.0", |
||||
|
"description": "function binding utility", |
||||
|
"keywords": [ |
||||
|
"bind", |
||||
|
"utility" |
||||
|
], |
||||
|
"dependencies": {}, |
||||
|
"scripts": [ |
||||
|
"index.js" |
||||
|
] |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
/** |
||||
|
* Slice reference. |
||||
|
*/ |
||||
|
|
||||
|
var slice = [].slice; |
||||
|
|
||||
|
/** |
||||
|
* Bind `obj` to `fn`. |
||||
|
* |
||||
|
* @param {Object} obj |
||||
|
* @param {Function|String} fn or string |
||||
|
* @return {Function} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
module.exports = function(obj, fn){ |
||||
|
if ('string' == typeof fn) fn = obj[fn]; |
||||
|
if ('function' != typeof fn) throw new Error('bind() requires a function'); |
||||
|
var args = slice.call(arguments, 2); |
||||
|
return function(){ |
||||
|
return fn.apply(obj, args.concat(slice.call(arguments))); |
||||
|
} |
||||
|
}; |
@ -0,0 +1,81 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "component-bind@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-bind", |
||||
|
"name": "component-bind", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-client" |
||||
|
] |
||||
|
], |
||||
|
"_from": "component-bind@1.0.0", |
||||
|
"_id": "component-bind@1.0.0", |
||||
|
"_inCache": true, |
||||
|
"_location": "/component-bind", |
||||
|
"_npmUser": { |
||||
|
"name": "tootallnate", |
||||
|
"email": "nathan@tootallnate.net" |
||||
|
}, |
||||
|
"_npmVersion": "1.4.9", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "component-bind@1.0.0", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-bind", |
||||
|
"name": "component-bind", |
||||
|
"rawSpec": "1.0.0", |
||||
|
"spec": "1.0.0", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/socket.io-client" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", |
||||
|
"_shasum": "00c608ab7dcd93897c0009651b1d3a8e1e73bbd1", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "component-bind@1.0.0", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-client", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/component/bind/issues" |
||||
|
}, |
||||
|
"component": { |
||||
|
"scripts": { |
||||
|
"bind/index.js": "index.js" |
||||
|
} |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "function binding utility", |
||||
|
"devDependencies": { |
||||
|
"mocha": "*", |
||||
|
"should": "*" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "00c608ab7dcd93897c0009651b1d3a8e1e73bbd1", |
||||
|
"tarball": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz" |
||||
|
}, |
||||
|
"homepage": "https://github.com/component/bind", |
||||
|
"keywords": [ |
||||
|
"bind", |
||||
|
"utility" |
||||
|
], |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "tootallnate", |
||||
|
"email": "nathan@tootallnate.net" |
||||
|
} |
||||
|
], |
||||
|
"name": "component-bind", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/component/bind.git" |
||||
|
}, |
||||
|
"version": "1.0.0" |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
node_modules |
||||
|
test |
@ -0,0 +1,4 @@ |
|||||
|
node_js: |
||||
|
- "0.8" |
||||
|
- "0.10" |
||||
|
language: node_js |
@ -0,0 +1,52 @@ |
|||||
|
|
||||
|
1.1.2 / 2014-02-10 |
||||
|
================== |
||||
|
|
||||
|
* package: rename to "component-emitter" |
||||
|
* package: update "main" and "component" fields |
||||
|
* Add license to Readme (same format as the other components) |
||||
|
* created .npmignore |
||||
|
* travis stuff |
||||
|
|
||||
|
1.1.1 / 2013-12-01 |
||||
|
================== |
||||
|
|
||||
|
* fix .once adding .on to the listener |
||||
|
* docs: Emitter#off() |
||||
|
* component: add `.repo` prop |
||||
|
|
||||
|
1.1.0 / 2013-10-20 |
||||
|
================== |
||||
|
|
||||
|
* add `.addEventListener()` and `.removeEventListener()` aliases |
||||
|
|
||||
|
1.0.1 / 2013-06-27 |
||||
|
================== |
||||
|
|
||||
|
* add support for legacy ie |
||||
|
|
||||
|
1.0.0 / 2013-02-26 |
||||
|
================== |
||||
|
|
||||
|
* add `.off()` support for removing all listeners |
||||
|
|
||||
|
0.0.6 / 2012-10-08 |
||||
|
================== |
||||
|
|
||||
|
* add `this._callbacks` initialization to prevent funky gotcha |
||||
|
|
||||
|
0.0.5 / 2012-09-07 |
||||
|
================== |
||||
|
|
||||
|
* fix `Emitter.call(this)` usage |
||||
|
|
||||
|
0.0.3 / 2012-07-11 |
||||
|
================== |
||||
|
|
||||
|
* add `.listeners()` |
||||
|
* rename `.has()` to `.hasListeners()` |
||||
|
|
||||
|
0.0.2 / 2012-06-28 |
||||
|
================== |
||||
|
|
||||
|
* fix `.off()` with `.once()`-registered callbacks |
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
test: |
||||
|
@./node_modules/.bin/mocha \
|
||||
|
--require should \
|
||||
|
--reporter spec |
||||
|
|
||||
|
.PHONY: test |
@ -0,0 +1,74 @@ |
|||||
|
# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter) |
||||
|
|
||||
|
Event emitter component. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
``` |
||||
|
$ component install component/emitter |
||||
|
``` |
||||
|
|
||||
|
## API |
||||
|
|
||||
|
### Emitter(obj) |
||||
|
|
||||
|
The `Emitter` may also be used as a mixin. For example |
||||
|
a "plain" object may become an emitter, or you may |
||||
|
extend an existing prototype. |
||||
|
|
||||
|
As an `Emitter` instance: |
||||
|
|
||||
|
```js |
||||
|
var Emitter = require('emitter'); |
||||
|
var emitter = new Emitter; |
||||
|
emitter.emit('something'); |
||||
|
``` |
||||
|
|
||||
|
As a mixin: |
||||
|
|
||||
|
```js |
||||
|
var Emitter = require('emitter'); |
||||
|
var user = { name: 'tobi' }; |
||||
|
Emitter(user); |
||||
|
|
||||
|
user.emit('im a user'); |
||||
|
``` |
||||
|
|
||||
|
As a prototype mixin: |
||||
|
|
||||
|
```js |
||||
|
var Emitter = require('emitter'); |
||||
|
Emitter(User.prototype); |
||||
|
``` |
||||
|
|
||||
|
### Emitter#on(event, fn) |
||||
|
|
||||
|
Register an `event` handler `fn`. |
||||
|
|
||||
|
### Emitter#once(event, fn) |
||||
|
|
||||
|
Register a single-shot `event` handler `fn`, |
||||
|
removed immediately after it is invoked the |
||||
|
first time. |
||||
|
|
||||
|
### Emitter#off(event, fn) |
||||
|
|
||||
|
* Pass `event` and `fn` to remove a listener. |
||||
|
* Pass `event` to remove all listeners on that event. |
||||
|
* Pass nothing to remove all listeners on all events. |
||||
|
|
||||
|
### Emitter#emit(event, ...) |
||||
|
|
||||
|
Emit an `event` with variable option args. |
||||
|
|
||||
|
### Emitter#listeners(event) |
||||
|
|
||||
|
Return an array of callbacks, or an empty array. |
||||
|
|
||||
|
### Emitter#hasListeners(event) |
||||
|
|
||||
|
Check if this emitter has `event` handlers. |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,21 @@ |
|||||
|
{ |
||||
|
"name": "emitter", |
||||
|
"description": "Event emitter", |
||||
|
"keywords": [ |
||||
|
"emitter", |
||||
|
"events" |
||||
|
], |
||||
|
"version": "1.1.2", |
||||
|
"license": "MIT", |
||||
|
"main": "index.js", |
||||
|
"homepage": "https://github.com/component/emitter", |
||||
|
"ignore": [ |
||||
|
"**/.*", |
||||
|
"node_modules", |
||||
|
"bower_components", |
||||
|
"test", |
||||
|
"Makefile", |
||||
|
"package.json", |
||||
|
"component.json" |
||||
|
] |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
"name": "emitter", |
||||
|
"repo": "component/emitter", |
||||
|
"description": "Event emitter", |
||||
|
"keywords": [ |
||||
|
"emitter", |
||||
|
"events" |
||||
|
], |
||||
|
"version": "1.1.2", |
||||
|
"scripts": [ |
||||
|
"index.js" |
||||
|
], |
||||
|
"license": "MIT" |
||||
|
} |
@ -0,0 +1,164 @@ |
|||||
|
|
||||
|
/** |
||||
|
* Expose `Emitter`. |
||||
|
*/ |
||||
|
|
||||
|
module.exports = Emitter; |
||||
|
|
||||
|
/** |
||||
|
* Initialize a new `Emitter`. |
||||
|
* |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
function Emitter(obj) { |
||||
|
if (obj) return mixin(obj); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Mixin the emitter properties. |
||||
|
* |
||||
|
* @param {Object} obj |
||||
|
* @return {Object} |
||||
|
* @api private |
||||
|
*/ |
||||
|
|
||||
|
function mixin(obj) { |
||||
|
for (var key in Emitter.prototype) { |
||||
|
obj[key] = Emitter.prototype[key]; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Listen on the given `event` with `fn`. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @param {Function} fn |
||||
|
* @return {Emitter} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.on = |
||||
|
Emitter.prototype.addEventListener = function(event, fn){ |
||||
|
this._callbacks = this._callbacks || {}; |
||||
|
(this._callbacks[event] = this._callbacks[event] || []) |
||||
|
.push(fn); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Adds an `event` listener that will be invoked a single |
||||
|
* time then automatically removed. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @param {Function} fn |
||||
|
* @return {Emitter} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.once = function(event, fn){ |
||||
|
var self = this; |
||||
|
this._callbacks = this._callbacks || {}; |
||||
|
|
||||
|
function on() { |
||||
|
self.off(event, on); |
||||
|
fn.apply(this, arguments); |
||||
|
} |
||||
|
|
||||
|
on.fn = fn; |
||||
|
this.on(event, on); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Remove the given callback for `event` or all |
||||
|
* registered callbacks. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @param {Function} fn |
||||
|
* @return {Emitter} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.off = |
||||
|
Emitter.prototype.removeListener = |
||||
|
Emitter.prototype.removeAllListeners = |
||||
|
Emitter.prototype.removeEventListener = function(event, fn){ |
||||
|
this._callbacks = this._callbacks || {}; |
||||
|
|
||||
|
// all
|
||||
|
if (0 == arguments.length) { |
||||
|
this._callbacks = {}; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
// specific event
|
||||
|
var callbacks = this._callbacks[event]; |
||||
|
if (!callbacks) return this; |
||||
|
|
||||
|
// remove all handlers
|
||||
|
if (1 == arguments.length) { |
||||
|
delete this._callbacks[event]; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
// remove specific handler
|
||||
|
var cb; |
||||
|
for (var i = 0; i < callbacks.length; i++) { |
||||
|
cb = callbacks[i]; |
||||
|
if (cb === fn || cb.fn === fn) { |
||||
|
callbacks.splice(i, 1); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Emit `event` with the given args. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @param {Mixed} ... |
||||
|
* @return {Emitter} |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.emit = function(event){ |
||||
|
this._callbacks = this._callbacks || {}; |
||||
|
var args = [].slice.call(arguments, 1) |
||||
|
, callbacks = this._callbacks[event]; |
||||
|
|
||||
|
if (callbacks) { |
||||
|
callbacks = callbacks.slice(0); |
||||
|
for (var i = 0, len = callbacks.length; i < len; ++i) { |
||||
|
callbacks[i].apply(this, args); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Return array of callbacks for `event`. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @return {Array} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.listeners = function(event){ |
||||
|
this._callbacks = this._callbacks || {}; |
||||
|
return this._callbacks[event] || []; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Check if this emitter has `event` handlers. |
||||
|
* |
||||
|
* @param {String} event |
||||
|
* @return {Boolean} |
||||
|
* @api public |
||||
|
*/ |
||||
|
|
||||
|
Emitter.prototype.hasListeners = function(event){ |
||||
|
return !! this.listeners(event).length; |
||||
|
}; |
@ -0,0 +1,81 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "component-emitter@1.1.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-emitter", |
||||
|
"name": "component-emitter", |
||||
|
"rawSpec": "1.1.2", |
||||
|
"spec": "1.1.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-parser" |
||||
|
] |
||||
|
], |
||||
|
"_from": "component-emitter@1.1.2", |
||||
|
"_id": "component-emitter@1.1.2", |
||||
|
"_inCache": true, |
||||
|
"_location": "/component-emitter", |
||||
|
"_npmUser": { |
||||
|
"name": "tootallnate", |
||||
|
"email": "nathan@tootallnate.net" |
||||
|
}, |
||||
|
"_npmVersion": "1.3.24", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "component-emitter@1.1.2", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-emitter", |
||||
|
"name": "component-emitter", |
||||
|
"rawSpec": "1.1.2", |
||||
|
"spec": "1.1.2", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/socket.io-parser" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", |
||||
|
"_shasum": "296594f2753daa63996d2af08d15a95116c9aec3", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "component-emitter@1.1.2", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/socket.io-parser", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/component/emitter/issues" |
||||
|
}, |
||||
|
"component": { |
||||
|
"scripts": { |
||||
|
"emitter/index.js": "index.js" |
||||
|
} |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Event emitter", |
||||
|
"devDependencies": { |
||||
|
"mocha": "*", |
||||
|
"should": "*" |
||||
|
}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "296594f2753daa63996d2af08d15a95116c9aec3", |
||||
|
"tarball": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz" |
||||
|
}, |
||||
|
"homepage": "https://github.com/component/emitter", |
||||
|
"main": "index.js", |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "tootallnate", |
||||
|
"email": "nathan@tootallnate.net" |
||||
|
} |
||||
|
], |
||||
|
"name": "component-emitter", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/component/emitter.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "make test" |
||||
|
}, |
||||
|
"version": "1.1.2" |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
components |
||||
|
build |
||||
|
node_modules |
@ -0,0 +1,5 @@ |
|||||
|
|
||||
|
0.0.2 / 2012-09-03 |
||||
|
================== |
||||
|
|
||||
|
* fix typo in package.json |
@ -0,0 +1,16 @@ |
|||||
|
|
||||
|
build: components index.js |
||||
|
@component build |
||||
|
|
||||
|
components: |
||||
|
@Component install |
||||
|
|
||||
|
clean: |
||||
|
rm -fr build components template.js |
||||
|
|
||||
|
test: |
||||
|
@node_modules/.bin/mocha \
|
||||
|
--require should \
|
||||
|
--reporter spec |
||||
|
|
||||
|
.PHONY: clean test |
@ -0,0 +1,24 @@ |
|||||
|
# inherit |
||||
|
|
||||
|
Prototype inheritance utility. |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
``` |
||||
|
$ component install component/inherit |
||||
|
``` |
||||
|
|
||||
|
## Example |
||||
|
|
||||
|
```js |
||||
|
var inherit = require('inherit'); |
||||
|
|
||||
|
function Human() {} |
||||
|
function Woman() {} |
||||
|
|
||||
|
inherit(Woman, Human); |
||||
|
``` |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,10 @@ |
|||||
|
{ |
||||
|
"name": "inherit", |
||||
|
"description": "Prototype inheritance utility", |
||||
|
"version": "0.0.3", |
||||
|
"keywords": ["inherit", "utility"], |
||||
|
"dependencies": {}, |
||||
|
"scripts": [ |
||||
|
"index.js" |
||||
|
] |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
module.exports = function(a, b){ |
||||
|
var fn = function(){}; |
||||
|
fn.prototype = b.prototype; |
||||
|
a.prototype = new fn; |
||||
|
a.prototype.constructor = a; |
||||
|
}; |
@ -0,0 +1,78 @@ |
|||||
|
{ |
||||
|
"_args": [ |
||||
|
[ |
||||
|
{ |
||||
|
"raw": "component-inherit@0.0.3", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-inherit", |
||||
|
"name": "component-inherit", |
||||
|
"rawSpec": "0.0.3", |
||||
|
"spec": "0.0.3", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-client" |
||||
|
] |
||||
|
], |
||||
|
"_from": "component-inherit@0.0.3", |
||||
|
"_id": "component-inherit@0.0.3", |
||||
|
"_inCache": true, |
||||
|
"_location": "/component-inherit", |
||||
|
"_npmUser": { |
||||
|
"name": "coreh", |
||||
|
"email": "thecoreh@gmail.com" |
||||
|
}, |
||||
|
"_npmVersion": "1.3.24", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"raw": "component-inherit@0.0.3", |
||||
|
"scope": null, |
||||
|
"escapedName": "component-inherit", |
||||
|
"name": "component-inherit", |
||||
|
"rawSpec": "0.0.3", |
||||
|
"spec": "0.0.3", |
||||
|
"type": "version" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"/engine.io-client" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", |
||||
|
"_shasum": "645fc4adf58b72b649d5cae65135619db26ff143", |
||||
|
"_shrinkwrap": null, |
||||
|
"_spec": "component-inherit@0.0.3", |
||||
|
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/node_modules/engine.io-client", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/component/inherit/issues" |
||||
|
}, |
||||
|
"component": { |
||||
|
"scripts": { |
||||
|
"inherit/index.js": "index.js" |
||||
|
} |
||||
|
}, |
||||
|
"dependencies": {}, |
||||
|
"description": "Prototype inheritance utility", |
||||
|
"devDependencies": {}, |
||||
|
"directories": {}, |
||||
|
"dist": { |
||||
|
"shasum": "645fc4adf58b72b649d5cae65135619db26ff143", |
||||
|
"tarball": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz" |
||||
|
}, |
||||
|
"homepage": "https://github.com/component/inherit", |
||||
|
"keywords": [ |
||||
|
"inherit", |
||||
|
"utility" |
||||
|
], |
||||
|
"maintainers": [ |
||||
|
{ |
||||
|
"name": "coreh", |
||||
|
"email": "thecoreh@gmail.com" |
||||
|
} |
||||
|
], |
||||
|
"name": "component-inherit", |
||||
|
"optionalDependencies": {}, |
||||
|
"readme": "ERROR: No README data found!", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/component/inherit.git" |
||||
|
}, |
||||
|
"version": "0.0.3" |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
|
||||
|
/** |
||||
|
* Module dependencies. |
||||
|
*/ |
||||
|
|
||||
|
var inherit = require('..'); |
||||
|
|
||||
|
describe('inherit(a, b)', function(){ |
||||
|
it('should inherit b\'s prototype', function(){ |
||||
|
function Loki(){} |
||||
|
function Animal(){} |
||||
|
|
||||
|
Animal.prototype.species = 'unknown'; |
||||
|
|
||||
|
inherit(Loki, Animal); |
||||
|
|
||||
|
var loki = new Loki; |
||||
|
loki.species.should.equal('unknown'); |
||||
|
loki.constructor.should.equal(Loki); |
||||
|
}) |
||||
|
}) |
@ -0,0 +1,40 @@ |
|||||
|
0.5.0 / 2014-10-11 |
||||
|
================== |
||||
|
|
||||
|
* Add `parse` function |
||||
|
|
||||
|
0.4.0 / 2014-09-21 |
||||
|
================== |
||||
|
|
||||
|
* Expand non-Unicode `filename` to the full ISO-8859-1 charset |
||||
|
|
||||
|
0.3.0 / 2014-09-20 |
||||
|
================== |
||||
|
|
||||
|
* Add `fallback` option |
||||
|
* Add `type` option |
||||
|
|
||||
|
0.2.0 / 2014-09-19 |
||||
|
================== |
||||
|
|
||||
|
* Reduce ambiguity of file names with hex escape in buggy browsers |
||||
|
|
||||
|
0.1.2 / 2014-09-19 |
||||
|
================== |
||||
|
|
||||
|
* Fix periodic invalid Unicode filename header |
||||
|
|
||||
|
0.1.1 / 2014-09-19 |
||||
|
================== |
||||
|
|
||||
|
* Fix invalid characters appearing in `filename*` parameter |
||||
|
|
||||
|
0.1.0 / 2014-09-18 |
||||
|
================== |
||||
|
|
||||
|
* Make the `filename` argument optional |
||||
|
|
||||
|
0.0.0 / 2014-09-18 |
||||
|
================== |
||||
|
|
||||
|
* Initial release |