@aarconada/urserver
Version:
Basic Server definitions to develope REST API with a node + express Server
833 lines (788 loc) • 80 kB
JavaScript
/**
* Created by ubuntu on 12/09/18.
*/
'use strict';
const server = require('./server')();
const _ = require('lodash');
const definitionoptions = {};
const definitions = {};
var Sequelize = null;
var model = null;
const SqlWhereParser = require('sql-where-parser');
const parser = new SqlWhereParser();
if(server.configuration.sequelize.enabled) {
Sequelize = require('sequelize-views-support');
model = new Sequelize(
server.configuration.sequelize.database.name,
server.configuration.sequelize.database.login,
server.configuration.sequelize.database.password,
server.configuration.sequelize.connection);
model
.authenticate()
.then(() => {
server.debug('MySQL Connection has been established succesfully.')
})
.catch((err) => {
server.debug('Unable to connect to the database', err);
});
if(server.configuration.sequelize.mustSync) {
model.sync(server.configuration.sequelize.sync);
}
}
module.exports.model = model;
module.exports.api = Sequelize;
module.exports.options = definitionoptions;
module.exports.define = function(options) {
if(model === null || !options || !options.modelname || !options.schema) {
return null;
}
options.configuration = !_.isUndefined(options.configuration) ? options.configuration : {};
options.configuration.icon = !_.isUndefined(options.configuration.icon) ? options.configuration.icon : 'photo';
options.configuration.treatAsView = !_.isUndefined(options.configuration.treatAsView) ? options.configuration.treatAsView : false;
options.configuration.viewDefinition = !_.isUndefined(options.configuration.viewDefinition) ? options.configuration.viewDefinition : '';
options.configuration.timestamps = !_.isUndefined(options.configuration.timestamps) ? options.configuration.timestamps : !options.configuration.treatAsView;
options.configuration.version = !_.isUndefined(options.configuration.version) ? options.configuration.version : !options.configuration.treatAsView;
options.configuration.paranoid = !_.isUndefined(options.configuration.paranoid) ? options.configuration.paranoid : !options.configuration.treatAsView;
options.GET = !_.isUndefined(options.GET) ? options.GET : {};
options.GET.all = !_.isUndefined(options.GET.all) ? options.GET.all : {};
options.GET.all.enabled = !_.isUndefined(options.GET.all.enabled) ? options.GET.all.enabled : true;
options.GET.all.token = !_.isUndefined(options.GET.all.token) ? options.GET.all.token : {};
options.GET.all.token.required = !_.isUndefined(options.GET.all.token.required) ? options.GET.all.token.required : true;
options.GET.all.token.ignoreExpiration = !_.isUndefined(options.GET.all.token.ignoreExpiration) ? options.GET.all.token.ignoreExpiration : false;
options.GET.all.help = !_.isUndefined(options.GET.all.help) ? options.GET.all.help : {};
options.GET.all.help.enabled = !_.isUndefined(options.GET.all.help.enabled) ? options.GET.all.help.enabled : true;
options.GET.all.help.route = !_.isUndefined(options.GET.all.help.route) ? options.GET.all.help.route : '/help';
options.GET.all.session = !_.isUndefined(options.GET.all.session) ? options.GET.all.session : {};
options.GET.all.session.required = !_.isUndefined(options.GET.all.session.required) ? options.GET.all.session.required : true;
options.GET.all.session.ignoreExpiration = !_.isUndefined(options.GET.all.session.allowedRoles) ? options.GET.all.session.allowedRoles : {};
options.GET.all.include = !_.isUndefined(options.GET.all.include) ? options.GET.all.include : {all: true};
options.GET.all.where = !_.isUndefined(options.GET.all.where) ? options.GET.all.where : {};
options.GET = !_.isUndefined(options.GET) ? options.GET : {};
options.GET.single = !_.isUndefined(options.GET.single) ? options.GET.single : {};
options.GET.single.enabled = !_.isUndefined(options.GET.single.enabled) ? options.GET.single.enabled : !options.configuration.treatAsView;
options.GET.single.token = !_.isUndefined(options.GET.single.token) ? options.GET.single.token : {};
options.GET.single.token.required = !_.isUndefined(options.GET.single.token.required) ? options.GET.single.token.required : true;
options.GET.single.token.ignoreExpiration = !_.isUndefined(options.GET.single.token.ignoreExpiration) ? options.GET.single.token.ignoreExpiration : false;
options.GET.single.help = !_.isUndefined(options.GET.single.help) ? options.GET.single.help : {};
options.GET.single.help.enabled = !_.isUndefined(options.GET.single.help.enabled) ? options.GET.single.help.enabled : true;
options.GET.single.help.route = !_.isUndefined(options.GET.single.help.route) ? options.GET.single.help.route : '/help';
options.GET.single.session = !_.isUndefined(options.GET.single.session) ? options.GET.single.session : {};
options.GET.single.session.required = !_.isUndefined(options.GET.single.session.required) ? options.GET.single.session.required : true;
options.GET.single.session.ignoreExpiration = !_.isUndefined(options.GET.single.session.allowedRoles) ? options.GET.single.session.allowedRoles : {};
options.GET.single.include = !_.isUndefined(options.GET.single.include) ? options.GET.single.include : {all: true};
options.GET.single.where = !_.isUndefined(options.GET.single.where) ? options.GET.single.where : {};
options.POST = !_.isUndefined(options.POST) ? options.POST : {};
options.POST.single = !_.isUndefined(options.POST.single) ? options.POST.single : {};
options.POST.single.enabled = !_.isUndefined(options.POST.single.enabled) ? options.POST.single.enabled : !options.configuration.treatAsView;
options.POST.single.token = !_.isUndefined(options.POST.single.token) ? options.POST.single.token : {};
options.POST.single.token.required = !_.isUndefined(options.POST.single.token.required) ? options.POST.single.token.required : true;
options.POST.single.token.ignoreExpiration = !_.isUndefined(options.POST.single.token.ignoreExpiration) ? options.POST.single.token.ignoreExpiration : false;
options.POST.single.help = !_.isUndefined(options.POST.single.help) ? options.POST.single.help : {};
options.POST.single.help.enabled = !_.isUndefined(options.POST.single.help.enabled) ? options.POST.single.help.enabled : true;
options.POST.single.help.route = !_.isUndefined(options.POST.single.help.route) ? options.POST.single.help.route : '/help';
options.POST.single.session = !_.isUndefined(options.POST.single.session) ? options.POST.single.session : {};
options.POST.single.session.required = !_.isUndefined(options.POST.single.session.required) ? options.POST.single.session.required : true;
options.POST.single.session.ignoreExpiration = !_.isUndefined(options.POST.single.session.allowedRoles) ? options.POST.single.session.allowedRoles : {};
options.PUT = !_.isUndefined(options.PUT) ? options.PUT : {};
options.PUT.single = !_.isUndefined(options.PUT.single) ? options.PUT.single : {};
options.PUT.single.enabled = !_.isUndefined(options.PUT.single.enabled) ? options.PUT.single.enabled : !options.configuration.treatAsView;
options.PUT.single.token = !_.isUndefined(options.PUT.single.token) ? options.PUT.single.token : {};
options.PUT.single.token.required = !_.isUndefined(options.PUT.single.token.required) ? options.PUT.single.token.required : true;
options.PUT.single.token.ignoreExpiration = !_.isUndefined(options.PUT.single.token.ignoreExpiration) ? options.PUT.single.token.ignoreExpiration : false;
options.PUT.single.help = !_.isUndefined(options.PUT.single.help) ? options.PUT.single.help : {};
options.PUT.single.help.enabled = !_.isUndefined(options.PUT.single.help.enabled) ? options.PUT.single.help.enabled : true;
options.PUT.single.help.route = !_.isUndefined(options.PUT.single.help.route) ? options.PUT.single.help.route : '/help';
options.PUT.single.session = !_.isUndefined(options.PUT.single.session) ? options.PUT.single.session : {};
options.PUT.single.session.required = !_.isUndefined(options.PUT.single.session.required) ? options.PUT.single.session.required : true;
options.PUT.single.session.ignoreExpiration = !_.isUndefined(options.PUT.single.session.allowedRoles) ? options.PUT.single.session.allowedRoles : {};
options.PUT = !_.isUndefined(options.PUT) ? options.PUT : {};
options.PUT.all = !_.isUndefined(options.PUT.all) ? options.PUT.all : {};
options.PUT.all.enabled = !_.isUndefined(options.PUT.all.enabled) ? options.PUT.all.enabled : !options.configuration.treatAsView;
options.PUT.all.token = !_.isUndefined(options.PUT.all.token) ? options.PUT.all.token : {};
options.PUT.all.token.required = !_.isUndefined(options.PUT.all.token.required) ? options.PUT.all.token.required : true;
options.PUT.all.token.ignoreExpiration = !_.isUndefined(options.PUT.all.token.ignoreExpiration) ? options.PUT.all.token.ignoreExpiration : false;
options.PUT.all.help = !_.isUndefined(options.PUT.all.help) ? options.PUT.all.help : {};
options.PUT.all.help.enabled = !_.isUndefined(options.PUT.all.help.enabled) ? options.PUT.all.help.enabled : true;
options.PUT.all.help.route = !_.isUndefined(options.PUT.all.help.route) ? options.PUT.all.help.route : '/help';
options.PUT.all.session = !_.isUndefined(options.PUT.all.session) ? options.PUT.all.session : {};
options.PUT.all.session.required = !_.isUndefined(options.PUT.all.session.required) ? options.PUT.all.session.required : true;
options.PUT.all.session.ignoreExpiration = !_.isUndefined(options.PUT.all.session.allowedRoles) ? options.PUT.all.session.allowedRoles : {};
options.DELETE = !_.isUndefined(options.DELETE) ? options.DELETE : {};
options.DELETE.single = !_.isUndefined(options.DELETE.single) ? options.DELETE.single : {};
options.DELETE.single.enabled = !_.isUndefined(options.DELETE.single.enabled) ? options.DELETE.single.enabled : !options.configuration.treatAsView;
options.DELETE.single.token = !_.isUndefined(options.DELETE.single.token) ? options.DELETE.single.token : {};
options.DELETE.single.token.required = !_.isUndefined(options.DELETE.single.token.required) ? options.DELETE.single.token.required : true;
options.DELETE.single.token.ignoreExpiration = !_.isUndefined(options.DELETE.single.token.ignoreExpiration) ? options.DELETE.single.token.ignoreExpiration : false;
options.DELETE.single.help = !_.isUndefined(options.DELETE.single.help) ? options.DELETE.single.help : {};
options.DELETE.single.help.enabled = !_.isUndefined(options.DELETE.single.help.enabled) ? options.DELETE.single.help.enabled : true;
options.DELETE.single.help.route = !_.isUndefined(options.DELETE.single.help.route) ? options.DELETE.single.help.route : '/help';
options.DELETE.single.session = !_.isUndefined(options.DELETE.single.session) ? options.DELETE.single.session : {};
options.DELETE.single.session.required = !_.isUndefined(options.DELETE.single.session.required) ? options.DELETE.single.session.required : true;
options.DELETE.single.session.ignoreExpiration = !_.isUndefined(options.DELETE.single.session.allowedRoles) ? options.DELETE.single.session.allowedRoles : {};
options.DELETE = !_.isUndefined(options.DELETE) ? options.DELETE : {};
options.DELETE.all = !_.isUndefined(options.DELETE.all) ? options.DELETE.all : {};
options.DELETE.all.enabled = !_.isUndefined(options.DELETE.all.enabled) ? options.DELETE.all.enabled : !options.configuration.treatAsView;
options.DELETE.all.token = !_.isUndefined(options.DELETE.all.token) ? options.DELETE.all.token : {};
options.DELETE.all.token.required = !_.isUndefined(options.DELETE.all.token.required) ? options.DELETE.all.token.required : true;
options.DELETE.all.token.ignoreExpiration = !_.isUndefined(options.DELETE.all.token.ignoreExpiration) ? options.DELETE.all.token.ignoreExpiration : false;
options.DELETE.all.help = !_.isUndefined(options.DELETE.all.help) ? options.DELETE.all.help : {};
options.DELETE.all.help.enabled = !_.isUndefined(options.DELETE.all.help.enabled) ? options.DELETE.all.help.enabled : true;
options.DELETE.all.help.route = !_.isUndefined(options.DELETE.all.help.route) ? options.DELETE.all.help.route : '/help';
options.DELETE.all.session = !_.isUndefined(options.DELETE.all.session) ? options.DELETE.all.session : {};
options.DELETE.all.session.required = !_.isUndefined(options.DELETE.all.session.required) ? options.DELETE.all.session.required : true;
options.DELETE.all.session.ignoreExpiration = !_.isUndefined(options.DELETE.all.session.allowedRoles) ? options.DELETE.all.session.allowedRoles : {};
const newModelDefinition = model.define(
options.modelname,
options.schema,
options.configuration);
definitionoptions[options.modelname] = options;
definitions[options.modelname] = newModelDefinition;
module.exports[options.modelname] = newModelDefinition;
return newModelDefinition;
};
module.exports.generateEndpoints = function() {
server.debug('Starting generation of endpoints for the model');
for(var currentOptions in definitionoptions) {
var currentDefinitionOptions = definitionoptions[currentOptions];
var currentDefinition = definitions[currentOptions];
const pluralName = currentDefinition.tableName;
const singularName = currentDefinition.name;
server.debug('Generating endpoints to model', currentDefinitionOptions.modelname);
if(currentDefinitionOptions.GET.all.enabled) {
generateGetAllEndpoint(currentDefinition, currentDefinitionOptions.GET.all, pluralName);
}
if(currentDefinitionOptions.GET.single.enabled) {
generateGetSingleEndpoint(currentDefinition, currentDefinitionOptions.GET.single, pluralName, singularName);
}
if(currentDefinitionOptions.POST.single.enabled) {
generatePostSingleEndpoint(currentDefinition, currentDefinitionOptions.POST.single, pluralName, singularName);
}
if(currentDefinitionOptions.PUT.all.enabled) {
generatePutAllEndpoint(currentDefinition, currentDefinitionOptions.PUT.all, pluralName, singularName);
}
if(currentDefinitionOptions.PUT.single.enabled) {
generatePutSingleEndpoint(currentDefinition, currentDefinitionOptions.PUT.single, pluralName, singularName);
}
if(currentDefinitionOptions.DELETE.all.enabled) {
generateDeleteAllEndpoint(currentDefinition, currentDefinitionOptions.DELETE.all, pluralName, singularName);
}
if(currentDefinitionOptions.DELETE.single.enabled) {
generateDeleteSingleEndpoint(currentDefinition, currentDefinitionOptions.DELETE.single, pluralName, singularName);
}
}
};
function generateGetAllEndpoint(currentDefinition, options, plural){
try {
const attributeList = [];
const filterList = [];
const parameters = [
{
name : 'sort',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows sort the response (?sort=-f1,+f2 = Sort by f1 Descending and f2 Ascending)'
},
{
name : 'fields',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows to specify the fields that will appear in the response (?fields=f1,f2 = Returns only f1 and f2)'
},
{
name : 'offset',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows to specify first record to return'
},
{
name : 'limit',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows to specify the number of records to return'
},
{
name : 'filter',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows to specify the where clause to filter result'
}
];
if(!currentDefinition['options'].treatAsView) {
parameters.push({
name : 'RelatedEntityNamefilter',
dataType : server.utils.dataType.STRING,
parameterType : server.utils.parameterType.QUERY,
required : false,
description : 'Allows to specify the where clause to filter the related entity with the specified name'
});
}
var singleResponse = {};
const attributes = Object.keys(currentDefinition['attributes']).sort(function(a, b) {return a.toLowerCase().localeCompare(b.toLowerCase())});
attributes.forEach(currentAttributeName => {
var currentAttribute = currentDefinition['attributes'][currentAttributeName];
var currentAttributeName = currentAttribute.fieldName;
var currentAttributeType = '' + currentAttribute.type;
var currentAttributeIsFilter= currentAttribute.isFilter ? currentAttribute.isFilter : false;
if(currentAttributeType === 'INTEGER') {
singleResponse[currentAttributeName] = 123;
} else if(currentAttributeType === 'DATETIME') {
singleResponse[currentAttributeName] = '1978-06-16T14:35:16.000Z';
} else if(currentAttributeType === 'DATE') {
singleResponse[currentAttributeName] = '1978-06-16';
} else if(currentAttributeType === 'TIME') {
singleResponse[currentAttributeName] = '14:35:16.000';
} else if(currentAttributeType === 'BOOLEAN') {
singleResponse[currentAttributeName] = true;
} else {
singleResponse[currentAttributeName] = 'abc...';
}
attributeList.push(currentAttributeName);
});
var definitionInclude = options.include;
if(!_.isUndefined(definitionInclude.all) && definitionInclude.all === true) {
definitionInclude = [];
Object.keys(currentDefinition.associations).forEach(currentAttribute => {
server.debug(currentDefinition.associations[currentAttribute].as);
if (currentDefinition.associations[currentAttribute].associationType === 'HasMany') {
server.debug('AS', currentDefinition.associations[currentAttribute].as);
definitionInclude.push({model: currentDefinition.associations[currentAttribute].target, as: currentDefinition.associations[currentAttribute].as});
} else {
definitionInclude.push({model: currentDefinition.associations[currentAttribute].target, as: currentDefinition.associations[currentAttribute].as});
}
});
}
const endpointConfiguration = {
name: 'Get ' + (currentDefinition['options'].treatAsView ? currentDefinition.name : plural.toLowerCase()),
description: (currentDefinition['options'].treatAsView ? 'This endpoint returns the execution of view ' + currentDefinition.name : 'This endpoint returns a list of ' + plural),
route: '/' + (currentDefinition['options'].treatAsView ? currentDefinition.name : plural.toLowerCase()),
method: server.utils.method.GET,
callback: options.callback ? options.callback : function (req, res, next, allowedResponses) {
var attributes = attributeList;
var include = definitionInclude;
var limit = null;
var offset = null;
var order = [];
var findWhere = [];
filterList.forEach(currentAttribute => {
if(!server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
server.utils.throwError(allowedResponses.unauthorized);
}
});
attributeList.forEach(currentAttribute => {
if(server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
server.debug('Auto filtering ' + currentAttribute + ' from Filters');
var filterObject = {};
filterObject[currentAttribute] = req.currentSession.filters[currentAttribute];
findWhere.push(filterObject);
}
});
Object.keys(req.query).forEach(currentParameter => {
if(currentParameter === 'fields') {
attributes = req.query.fields.split(',');
include = [];
} else if(currentParameter === 'limit') {
limit = +req.query.limit;
}else if(currentParameter === 'offset') {
offset = +req.query.offset;
}else if(currentParameter === 'sort') {
req.query.sort.split(',').forEach(currentSortValue => {
currentSortValue = currentSortValue.trim();
var sortType = 'ASC';
var fieldName = '';
if (currentSortValue[0] === '-') {
sortType = 'DESC';
fieldName = currentSortValue.substring(1);
} else if (currentSortValue[0] === '+') {
fieldName = currentSortValue.substring(1);
} else {
fieldName = currentSortValue;
}
order.push([fieldName, sortType]);
});
} else if(currentParameter === 'filter') {
findWhere.push(getFilterWhere(currentDefinition.name, req.query.filter));
} else if(currentParameter.endsWith('filter')) {
const relatedEntityName = currentParameter.replace('filter', '');
var validFilter = false;
include.forEach(currentInclude => {
if(currentInclude.model.name.toUpperCase() === relatedEntityName.toUpperCase()) {
validFilter = true;
currentInclude.where = getFilterWhere(currentInclude.model.name, req.query[currentParameter]);
}
});
if(!validFilter) {
server.utils.throwError(server.defaultResponses.invalid_parameter);
}
} else {
server.utils.throwError(server.defaultResponses.invalid_parameter);
}
});
server.debug('Getting list of', plural);
return currentDefinition.findAll({
subQuery : true,
attributes : attributes,
include : include,
where : findWhere,
limit : limit,
offset : offset,
order : order
}).then(elements => {
return elements;
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_get_list, err);
});
},
token: options.token,
help: options.help,
session: options.session,
parameters: parameters,
responses: {
entity_unable_get_list : server.defaultResponses.entity_unable_get_list,
unauthorized : server.defaultResponses.unauthorized
},
success: [singleResponse],
transactional: false,
};
server.endpointmanager.addEndpoint(endpointConfiguration);
} catch(err) {
server.debug(err);
throw err;
}
}
function getFilterWhere (entityName, filterString) {
const tableFieldParser = RegExp(/\w+\.\w+/i);
const parsed = parser.parse(filterString, (operatorValue, operands) => {
var includeCurrentParsedElement = true;
if (!_.isNull(tableFieldParser.exec(operands[0])) || !_.isNull(tableFieldParser.exec(operands[1]))) {
if (!_.isNull(tableFieldParser.exec(operands[0]))) {
const whereParts = operands[0].split('.');
if (entityName.toUpperCase() !== whereParts[0].toUpperCase()) {
server.utils.throwError(server.defaultResponses.invalid_filter);
} else {
operands[0] = whereParts[1];
}
}
if (!_.isNull(tableFieldParser.exec(operands[1]))) {
const whereParts = operands[1].split('.');
if (currentDefinition.name.toUpperCase() !== whereParts[0].toUpperCase()) {
server.utils.throwError(server.defaultResponses.invalid_filter);
} else {
operands[1] = whereParts[1];
}
}
}
switch (operatorValue) {
case 'AND':
if (!_.isUndefined(operands[0]) && !_.isUndefined(operands[1])) {
return {
[server.sequelize.api.Op.and]: operands
};
} else if (!_.isUndefined(operands[0])) {
return operands[0];
} else if (!_.isUndefined(operands[1])) {
return operands[1];
}
case 'OR':
return {
[server.sequelize.api.Op.or]: operands
};
case '!=':
return {
[operands[0]]: {
[server.sequelize.api.Op.ne]: operands[1]
}
};
case '<=':
return {
[operands[0]]: {
[server.sequelize.api.Op.lte]: operands[1]
}
};
case '>=':
return {
[operands[0]]: {
[server.sequelize.api.Op.gte]: operands[1]
}
};
case '=':
return {
[operands[0]]: operands[1]
};
case '>':
return {
[operands[0]]: {
[server.sequelize.api.Op.gt]: operands[1]
}
};
case '<':
return {
[operands[0]]: {
[server.sequelize.api.Op.lt]: operands[1]
}
};
default:
server.utils.throwError(server.defaultResponses.invalid_filter);
}
});
return parsed;
}
function generateGetSingleEndpoint(currentDefinition, options, plural, singular){
try {
const filterList = [];
const attributeList = [];
var singleResponse = {};
const attributes = Object.keys(currentDefinition['attributes']).sort(function(a, b) {return a.toLowerCase().localeCompare(b.toLowerCase())});
attributes.forEach(currentAttributeName => {
var currentAttribute = currentDefinition['attributes'][currentAttributeName];
var currentAttributeName = currentAttribute.fieldName;
var currentAttributeType = '' + currentAttribute.type;
var currentAttributeIsFilter= currentAttribute.isFilter ? currentAttribute.isFilter : false;
if(currentAttributeType === 'INTEGER') {
singleResponse[currentAttributeName] = 123;
} else if(currentAttributeType === 'DATETIME') {
singleResponse[currentAttributeName] = '1978-06-16T14:35:16.000Z';
} else if(currentAttributeType === 'DATE') {
singleResponse[currentAttributeName] = '1978-06-16';
} else if(currentAttributeType === 'TIME') {
singleResponse[currentAttributeName] = '14:35:16.000';
} else if(currentAttributeType === 'BOOLEAN') {
singleResponse[currentAttributeName] = true;
} else {
singleResponse[currentAttributeName] = 'abc...';
}
attributeList.push(currentAttributeName);
});
const endpointConfiguration = {
name: 'Get ' + singular,
description: 'This endpoint returns the ' + singular.toLowerCase() + ' associated with the :id received',
route: '/' + plural.toLowerCase() + '/:id',
method: server.utils.method.GET,
callback: options.callback ? options.callback : function (req, res, next, allowedResponses) {
server.debug('Getting', singular.toLowerCase());
filterList.forEach(currentAttribute => {
if(!server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
throw allowedResponses.unauthorized;
}
});
var findWhere = [
{id: req.params.id}
];
attributeList.forEach(currentAttribute => {
if (req.body[currentAttribute]) {
assignations[currentAttribute] = req.body[currentAttribute];
}
if(server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
server.debug('Auto filtering ' + currentAttribute + ' from Filters');
var filterObject = {};
filterObject[currentAttribute] = req.currentSession.filters[currentAttribute];
findWhere.push(filterObject);
}
});
return currentDefinition.findAll({
subQuery : false,
attributes : attributeList,
where : {[server.sequelize.api.Op.and]: findWhere},
include : options.include
}).then(element => {
if(element === null) server.utils.throwError(allowedResponses.entity_element_not_found);
return element[0];
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_get_element, err);
});
},
token: options.token,
help: options.help,
session: options.session,
parameters: [
{
name: 'id',
dataType: server.utils.dataType.INTEGER,
parameterType: server.utils.parameterType.PARAM,
required: true,
description: 'The id of the finded ' + singular.toLowerCase()
}
],
responses: {
entity_element_not_found: server.defaultResponses.entity_element_not_found,
entity_unable_get_element: server.defaultResponses.entity_unable_get_element
},
success: singleResponse,
transactional: false,
};
server.endpointmanager.addEndpoint(endpointConfiguration);
Object.keys(currentDefinition.associations).forEach(currentAttribute => {
var singleResponse = {};
var singleFilters = [];
const currentTarget = currentDefinition.associations[currentAttribute].target;
const attributes = Object.keys(currentTarget.attributes).sort(function(a, b) {return a.toLowerCase().localeCompare(b.toLowerCase())});
attributes.forEach(currentAttributeName => {
var currentAttribute = currentTarget.attributes[currentAttributeName];
var currentAttributeName = currentAttribute.fieldName;
var currentAttributeType = '' + currentAttribute.type;
var currentAttributeIsFilter= currentAttribute.isFilter ? currentAttribute.isFilter : false;
/*
if(currentAttributeIsFilter) {
if(currentAttributeName === 'id') {
filterList.push(singular + 'Id');
} else {
filterList.push(currentAttributeName);
}
}
*/
if(currentAttributeType === 'INTEGER') {
singleResponse[currentAttributeName] = 123;
} else if(currentAttributeType === 'DATETIME') {
singleResponse[currentAttributeName] = '1978-06-16T14:35:16.000Z';
} else if(currentAttributeType === 'DATE') {
singleResponse[currentAttributeName] = '1978-06-16';
} else if(currentAttributeType === 'TIME') {
singleResponse[currentAttributeName] = '14:35:16.000';
} else if(currentAttributeType === 'BOOLEAN') {
singleResponse[currentAttributeName] = true;
} else {
singleResponse[currentAttributeName] = 'abc...';
}
});
if(currentDefinition.associations[currentAttribute].isMultiAssociation) {
singleResponse = [singleResponse];
}
const endpointConfiguration = {
name: 'Get ' + singular + ' ' + currentAttribute,
description: 'This endpoint returns the ' + currentAttribute + ' of the ' + singular.toLowerCase() + ' associated with the :id received',
route: '/' + plural.toLowerCase() + '/:id/' + currentAttribute,
method: server.utils.method.GET,
callback: options.callback ? options.callback : function (req, res, next, allowedResponses) {
server.debug('Getting list of', plural);
singleFilters.forEach(currentAttribute => {
if(!server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
throw allowedResponses.unauthorized;
}
});
var findWhere = [
{id: req.params.id}
]
attributeList.forEach(currentAttribute => {
if (req.body[currentAttribute]) {
assignations[currentAttribute] = req.body[currentAttribute];
}
if(server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
server.debug('Auto filtering ' + currentAttribute + ' from Filters');
var filterObject = {};
filterObject[currentAttribute] = req.currentSession.filters[currentAttribute];
findWhere.push(filterObject);
}
});
return currentDefinition.findOne({
subQuery : false,
where : {[server.sequelize.api.Op.and]: findWhere},
include : options.include
}).then(element => {
if(element === null) server.utils.throwError(allowedResponses.entity_element_not_found);
const relationGetterCallback = element['get' + currentAttribute]();
return relationGetterCallback.then(relatedEntities => {
return relatedEntities;
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_get_element, err);
})
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_get_element, err);
});
},
token: options.token,
help: options.help,
session: options.session,
parameters: [
{
name: 'id',
dataType: server.utils.dataType.INTEGER,
parameterType: server.utils.parameterType.PARAM,
required: true,
description: 'The id of the finded ' + singular.toLowerCase()
}
],
responses: {
entity_element_not_found: server.defaultResponses.entity_element_not_found,
entity_unable_get_element: server.defaultResponses.entity_unable_get_element,
unauthorized: server.defaultResponses.unauthorized
},
success: singleResponse,
transactional: false,
};
server.endpointmanager.addEndpoint(endpointConfiguration);
});
} catch(err) {
server.debug(err);
throw err;
}
}
function generatePostSingleEndpoint(currentDefinition, options, plural, singular){
try {
const parameters = [];
const attributeList = [];
const fileList = [];
const filterList = [];
var singleResponse = {};
const attributes = Object.keys(currentDefinition['attributes']).sort(function(a, b) {return a.toLowerCase().localeCompare(b.toLowerCase())});
attributes.forEach(currentAttributeName => {
var currentAttribute = currentDefinition['attributes'][currentAttributeName];
var currentAttributeName = currentAttribute.fieldName;
var currentAttributeType = '' + currentAttribute.type;
var dataType = server.utils.dataType.STRING;
var description = '';
var currentAttributeIsFilter= currentAttribute.isFilter ? currentAttribute.isFilter : false;
if(!currentAttribute._autoGenerated) {
if(!_.isUndefined(currentAttribute.resource)) {
parameters.push({
name: currentAttributeName,
parameterType: server.utils.parameterType.FILE,
required: !currentAttribute.allowNull,
description: description
});
fileList.push(currentAttribute);
} else {
if (currentAttributeType === 'INTEGER') {
dataType = server.utils.dataType.INTEGER;
} else if (currentAttributeType === 'FLOAT' || currentAttributeType === 'REAL' || currentAttributeType === 'DOUBLE' || currentAttributeType === 'DECIMAL') {
dataType = server.utils.dataType.FLOAT;
} else if (currentAttributeType === 'DATETIME' || currentAttributeType === 'DATE' || currentAttributeType === 'TIME' || currentAttributeType === 'DATEONLY') {
dataType = server.utils.dataType.DATE;
} else if (currentAttributeType === 'BOOLEAN') {
dataType = server.utils.dataType.BOOLEAN;
}
if (currentAttribute.unique) {
description += '(UNIQUE)';
}
if (currentAttribute.references) {
const referenceValue = currentAttribute.references;
description += 'Key of the related ' + referenceValue.model + ' of the ' + singular;
}
parameters.push({
name: currentAttributeName,
dataType: dataType,
parameterType: server.utils.parameterType.BODY,
required: !currentAttribute.allowNull,
description: description
});
attributeList.push(currentAttributeName);
}
}
});
const endpointConfiguration = {
name : !_.isUndefined(options.name) ? options.name : 'Create ' + singular,
description : !_.isUndefined(options.description) ? options.description : 'This endpoint creates a ' + singular.toLowerCase() + ' in the database',
route : '/' + plural.toLowerCase(),
method : server.utils.method.POST,
callback : !_.isUndefined(options.callback) ? options.callback : function (req, res, next, allowedResponses, transaction) {
server.debug('Trying to create ' + singular.toLowerCase());
filterList.forEach(currentAttribute => {
if(!server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
throw allowedResponses.unauthorized;
}
});
var assignations = {};
attributeList.forEach(currentAttribute => {
if (req.body[currentAttribute]) {
assignations[currentAttribute] = req.body[currentAttribute];
}
if(server.utils.valueInList(req.currentSession.filters, currentAttribute)) {
server.debug('AutoAssigning ' + currentAttribute + ' from Filters');
assignations[currentAttribute] = req.currentSession.filters[currentAttribute];
}
});
fileList.forEach(currentFile => {
var fieldName = currentFile.fieldName;
if(!_.isUndefined(req.files) && req.files !== null && req.files[fieldName]) {
var resourcePath = !_.isUndefined(currentFile.resource.path) ? currentFile.resource.path : '';
var fileName = +(new Date());
var fileNameParts = req.files[fieldName].name.split('.');
if (fileNameParts.length === 2) fileName += '.' + fileNameParts[1];
if (!_.isUndefined(currentFile.resource.saveInCloudStorage) && currentFile.resource.saveInCloudStorage === true && server.configuration.google.storage.enabled) {
server.googlestorage.saveFile(resourcePath + '/' + fileName, req.files[fieldName].data, req.files[fieldName].mimetype);
assignations[fieldName] = resourcePath + '/' + fileName;
} else {
assignations[fieldName] = server.fileSystem.saveResource(resourcePath, req.files[fieldName], fileName);
}
}
});
return currentDefinition.create(
assignations,
{
transaction: transaction
})
.then(newElement => {
server.socket.Emit(singular.toUpperCase() + server.socket.Events.EntityCreated, newElement);
return {
id: newElement.id
};
})
.catch(err => {
server.debug(err);
throw allowedResponses.entity_unable_post_element;
});
},
token : options.token,
help : options.help,
session : options.session,
parameters : !_.isUndefined(options.parameters) ? options.parameters : parameters,
responses : {
missing_parameter : server.defaultResponses.missing_parameter,
entity_unable_post_element : server.defaultResponses.entity_unable_post_element,
invalid_parameter_data_type : server.defaultResponses.invalid_parameter_data_type,
unauthorized : server.defaultResponses.unauthorized
},
success : {id: 123},
transactional : true,
};
server.endpointmanager.addEndpoint(endpointConfiguration);
} catch(err) {
server.debug(err);
throw err;
}
}
function generatePutSingleEndpoint(currentDefinition, options, plural, singular){
try {
const parameters = [
{
name: 'id',
dataType: server.utils.dataType.INTEGER,
parameterType: server.utils.parameterType.PARAM,
required: true,
description: 'The id of the finded ' + singular.toLowerCase()
}
];
const attributeList = [];
const filterList = [];
const fileList = [];
//var singleResponse = {};
const attributes = Object.keys(currentDefinition['attributes']).sort(function(a, b) {return a.toLowerCase().localeCompare(b.toLowerCase())});
attributes.forEach(currentAttributeName => {
var currentAttribute = currentDefinition['attributes'][currentAttributeName];
var currentAttributeName = currentAttribute.fieldName;
var currentAttributeType = '' + currentAttribute.type;
var dataType = server.utils.dataType.STRING;
var description = '';
var currentAttributeIsFilter= currentAttribute.isFilter ? currentAttribute.isFilter : false;
if(!currentAttribute._autoGenerated) {
if(!_.isUndefined(currentAttribute.resource)) {
parameters.push({
name: currentAttributeName,
parameterType: server.utils.parameterType.FILE,
required: false,
description: description
});
fileList.push(currentAttribute);
} else {
if (currentAttributeType === 'INTEGER') {
dataType = server.utils.dataType.INTEGER;
} else if (currentAttributeType === 'FLOAT' || currentAttributeType === 'REAL' || currentAttributeType === 'DOUBLE' || currentAttributeType === 'DECIMAL') {
dataType = server.utils.dataType.FLOAT;
} else if (cu