2016-05-18 22:50:06 +02:00
|
|
|
'use strict';
|
|
|
|
|
2016-06-07 10:50:15 +02:00
|
|
|
angular.module('ffffng').factory('Resources', function (_, Constraints, Validator, ErrorTypes) {
|
2016-06-07 14:08:04 +02:00
|
|
|
function respond(res, httpCode, data, type) {
|
|
|
|
switch (type) {
|
|
|
|
case 'html':
|
|
|
|
res.writeHead(httpCode, {'Content-Type': 'text/html'});
|
|
|
|
res.end(data);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
res.writeHead(httpCode, {'Content-Type': 'application/json'});
|
|
|
|
res.end(JSON.stringify(data));
|
|
|
|
break;
|
|
|
|
}
|
2016-05-18 22:50:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
getData: function (req) {
|
|
|
|
return _.extend({}, req.body, req.params, req.query);
|
|
|
|
},
|
|
|
|
|
2016-06-07 10:50:15 +02:00
|
|
|
getValidRestParams: function(type, req, callback) {
|
|
|
|
var constraints = Constraints.rest[type];
|
|
|
|
if (!_.isPlainObject(constraints)) {
|
|
|
|
Logger.tag('validation', 'rest').error('Unknown REST resource type: {}', type);
|
|
|
|
return callback({data: 'Internal error.', type: ErrorTypes.internalError});
|
|
|
|
}
|
|
|
|
|
|
|
|
var data = this.getData(req);
|
|
|
|
|
|
|
|
var restParams = {};
|
|
|
|
_.each(_.keys(constraints), function (key) {
|
|
|
|
var value = data[key];
|
|
|
|
restParams[key] = _.isUndefined(value) && !_.isUndefined(constraints[key].default)
|
|
|
|
? constraints[key].default
|
|
|
|
: value;
|
|
|
|
});
|
|
|
|
|
|
|
|
var areValidParams = Validator.forConstraints(constraints);
|
|
|
|
if (!areValidParams(restParams)) {
|
|
|
|
return callback({data: 'Invalid REST parameters.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(null, restParams);
|
|
|
|
},
|
|
|
|
|
2016-06-07 12:39:52 +02:00
|
|
|
filter: function (entities, allowedFilterFields, restParams) {
|
|
|
|
var query = restParams.q;
|
|
|
|
if (!query) {
|
|
|
|
return entities;
|
|
|
|
}
|
|
|
|
|
|
|
|
query = _.toLower(query.trim());
|
|
|
|
|
|
|
|
return _.filter(entities, function (entity) {
|
|
|
|
return _.some(allowedFilterFields, function (field) {
|
|
|
|
var value = entity[field];
|
2016-06-07 12:45:23 +02:00
|
|
|
if (_.isNumber(value)) {
|
|
|
|
value = value.toString();
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:39:52 +02:00
|
|
|
if (!_.isString(value) || _.isEmpty(value)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = _.toLower(value);
|
|
|
|
if (field === 'mac') {
|
|
|
|
return _.includes(value.replace(/:/g, ''), query.replace(/:/g, ''));
|
|
|
|
}
|
|
|
|
|
|
|
|
return _.includes(value, query);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-06-07 11:58:29 +02:00
|
|
|
sort: function (entities, allowedSortFields, restParams) {
|
2016-06-07 12:39:52 +02:00
|
|
|
var sortField = _.includes(allowedSortFields, restParams._sortField) ? restParams._sortField : undefined;
|
2016-06-07 11:58:29 +02:00
|
|
|
if (!sortField) {
|
|
|
|
return entities;
|
|
|
|
}
|
|
|
|
|
|
|
|
var sorted = _.sortBy(entities, [sortField]);
|
|
|
|
|
|
|
|
return restParams._sortDir === 'ASC' ? sorted : _.reverse(sorted);
|
|
|
|
},
|
|
|
|
|
|
|
|
getPageEntities: function (entities, restParams) {
|
|
|
|
var page = restParams._page;
|
|
|
|
var perPage = restParams._perPage;
|
|
|
|
|
|
|
|
return entities.slice((page - 1) * perPage, page * perPage);
|
|
|
|
},
|
|
|
|
|
2016-05-18 22:50:06 +02:00
|
|
|
success: function (res, data) {
|
2016-06-07 14:08:04 +02:00
|
|
|
respond(res, 200, data, 'json');
|
|
|
|
},
|
|
|
|
|
|
|
|
successHtml: function (res, html) {
|
|
|
|
respond(res, 200, html, 'html');
|
2016-05-18 22:50:06 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
error: function (res, err) {
|
2016-06-07 14:08:04 +02:00
|
|
|
respond(res, err.type.code, err.data, 'json');
|
2016-05-18 22:50:06 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|