Update generated API && support aliases for Bookshelf

This commit is contained in:
Aurélien Georget 2017-01-11 17:53:40 +01:00
parent 64ce44495e
commit 5b74588653
5 changed files with 192 additions and 276 deletions

View File

@ -88,7 +88,7 @@ module.exports = function (strapi) {
// Register the final model for Bookshelf.
const loadedModel = {
tableName: definition.tableName,
hasTimestamps: _.get(definition, 'options.timestamps') || true
hasTimestamps: _.get(definition, 'options.timestamps') === true
};
// Initialize the global variable with the
@ -122,8 +122,17 @@ module.exports = function (strapi) {
});
};
loadedModel.hidden = _.keys(_.keyBy(_.filter(definition.attributes, (value, key) => {
if (value.hasOwnProperty('columnName') && !_.isEmpty(value.columnName) && value.columnName !== key) {
return true;
}
}), 'columnName'));
const ORM = new bookshelf(strapi.connections[connectionName]);
// Load plugins
ORM.plugin('visibility');
global[globalName] = ORM.Model.extend(loadedModel);
global[pluralize(globalName)] = ORM.Collection.extend({
model: global[globalName]
@ -165,20 +174,20 @@ module.exports = function (strapi) {
}
});
loadedModel[name] = () => {
return this.hasOne(global[_.capitalize(details.model)], FK);
loadedModel[name] = function () {
return this.hasOne(global[_.capitalize(details.model)], _.get(strapi.models[details.model].attributes, `${FK}.columnName`) || FK);
};
break;
}
case 'hasMany': {
loadedModel[name] = () => {
loadedModel[name] = function () {
return this.hasMany(global[_.capitalize(details.collection)], details.via);
};
break;
}
case 'belongsTo': {
loadedModel[name] = () => {
return this.belongsTo(global[_.capitalize(details.model)], name);
loadedModel[name] = function () {
return this.belongsTo(global[_.capitalize(details.model)], _.get(details, 'columnName') || name);
};
break;
}
@ -203,7 +212,7 @@ module.exports = function (strapi) {
relationship.attribute = pluralize.singular(details.via);
}
loadedModel[name] = () => {
loadedModel[name] = function () {
return this.belongsToMany(global[_.capitalize(details.collection)], tableName, relationship.attribute + '_' + relationship.column, details.attribute + '_' + details.column);
};
break;

View File

@ -1,122 +1,114 @@
'use strict';
/**
* A set of functions called "actions" for `<%= globalID %>`
* <%= filename %> controller
*
* @description: A set of functions called "actions" for managing `<%= globalID %>`.
*/
module.exports = {
/**
* Get <%= subId || id %> entries.
* Retrieve <%= subId || id %> records.
*
* @return {Object|Array}
*/
find: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.fetchAll(ctx.query);
} catch (err) {
ctx.body = err;
}
find: async (ctx) => {
const data = await strapi.services.<%= subId || id %>.fetchAll(ctx.query);
// Send 200 `ok`
ctx.send(data);
},
/**
* Get a specific <%= subId || id %>.
*
* @return {Object|Array}
*/
findOne: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.fetch(ctx.params)
} catch (err) {
ctx.body = err;
}
},
/**
* Create a/an <%= subId || id %> entry.
* Retrieve a <%= subId || id %> record.
*
* @return {Object}
*/
create: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.add(ctx.request.body);
} catch (err) {
ctx.body = err;
}
findOne: async (ctx) => {
const data = await strapi.services.<%= subId || id %>.fetch(ctx.params);
// Send 200 `ok`
ctx.send(data);
},
/**
* Update a/an <%= subId || id %> entry.
* Create a/an <%= subId || id %> record.
*
* @return {Object}
*/
create: async (ctx) => {
const data = await strapi.services.<%= subId || id %>.add(ctx.request.body);
// Send 201 `created`
ctx.created(data);
},
/**
* Update a/an <%= subId || id %> record.
*
* @return {Object}
*/
update: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.edit(ctx.params, ctx.request.body) ;
} catch (err) {
ctx.body = err;
}
const data = await strapi.services.<%= subId || id %>.edit(ctx.params, ctx.request.body) ;
// Send 200 `ok`
ctx.send(data);
},
/**
* Destroy a/an <%= subId || id %> entry.
* Destroy a/an <%= subId || id %> record.
*
* @return {Object}
*/
destroy: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.remove(ctx.params);
} catch (err) {
ctx.body = err;
}
const data = await strapi.services.<%= subId || id %>.remove(ctx.params);
// Send 200 `ok`
ctx.send(data);
},
/**
* Add relation to a specific <%= subId || id %>.
* Add relation to a/an <%= subId || id %> record.
*
* @return {Object}
*/
createRelation: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.addRelation(ctx.params, ctx.request.body);
} catch (err) {
ctx.status = 400;
ctx.body = err;
}
const data = await strapi.services.<%= subId || id %>.addRelation(ctx.params, ctx.request.body);
// Send 200 `ok`
ctx.send(data);
},
/**
* Update relation to a specific <%= subId || id %>.
* Update relation to a/an <%= subId || id %> record.
*
* @return {Object}
*/
updateRelation: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.editRelation(ctx.params, ctx.request.body);
} catch (err) {
ctx.status = 400;
ctx.body = err;
}
const data = await strapi.services.<%= subId || id %>.editRelation(ctx.params, ctx.request.body);
// Send 200 `ok`
ctx.send(data);
},
/**
* Destroy relation to a specific <%= subId || id %>.
* Destroy relation to a/an <%= subId || id %> record.
*
* @return {Object}
*/
destroyRelation: async (ctx, next) => {
try {
ctx.body = await strapi.services.<%= subId || id %>.removeRelation(ctx.params, ctx.request.body);
} catch (err) {
ctx.status = 400;
ctx.body = err;
}
const data = await strapi.services.<%= subId || id %>.removeRelation(ctx.params, ctx.request.body);
// Send 200 `ok`
ctx.send(data);
}
};

View File

@ -1,7 +1,9 @@
'use strict';
/**
* Module dependencies
* <%= filename %> service
*
* @description: A set of functions similar to controller's actions to avoid code duplication.
*/
// Public dependencies.
@ -10,10 +12,6 @@ const _ = require('lodash');
// Strapi utilities.
const utils = require('strapi-bookshelf/lib/utils/');
/**
* A set of functions called "actions" for `<%= globalID %>`
*/
module.exports = {
/**
@ -22,17 +20,9 @@ module.exports = {
* @return {Promise}
*/
fetchAll: params => {
return new Promise((resolve, reject) => {
<%= globalID %>.forge(params).query(params).fetchAll({
withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= subId || id %>.associations, {autoPopulate: false}), 'alias'))
})
.then(<%= subIdPluralized || idPluralized %> => {
resolve(<%= subIdPluralized || idPluralized %>);
})
.catch(err => {
reject(err);
});
fetchAll: (params) => {
return <%= globalID %>.forge(params).query(params).fetchAll({
withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= subId || id %>.associations, {autoPopulate: false}), 'alias'))
});
},
@ -42,17 +32,9 @@ module.exports = {
* @return {Promise}
*/
fetch: params => {
return new Promise((resolve, reject) => {
<%= globalID %>.forge(_.pick(params, 'id')).fetch({
withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= subId || id %>.associations, {autoPopulate: false}), 'alias'))
})
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
fetch: (params) => {
return <%= globalID %>.forge(_.pick(params, 'id')).fetch({
withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= subId || id %>.associations, {autoPopulate: false}), 'alias'))
});
},
@ -62,16 +44,8 @@ module.exports = {
* @return {Promise}
*/
add: values => {
return new Promise((resolve, reject) => {
<%= globalID %>.forge(values).save()
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
});
add: (values) => {
return <%= globalID %>.forge(values).save();
},
/**
@ -81,15 +55,7 @@ module.exports = {
*/
edit: (params, values) => {
return new Promise((resolve, reject) => {
<%= globalID %>.forge(params).save(values, {path: true})
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
});
return <%= globalID %>.forge(params).save(values, {path: true});
},
/**
@ -98,16 +64,8 @@ module.exports = {
* @return {Promise}
*/
remove: params => {
return new Promise((resolve, reject) => {
<%= globalID %>.forge(params).destroy()
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
});
remove: (params) => {
return <%= globalID %>.forge(params).destroy();
},
/**
@ -117,47 +75,33 @@ module.exports = {
*/
addRelation: (params, values) => {
return new Promise((resolve, reject) => {
const relation = _.find(strapi.models.<%= subId || id %>.associations, {alias: params.relation});
const relation = _.find(strapi.models.<%= subId || id %>.associations, {alias: params.relation});
if (!_.isEmpty(relation) && _.isArray(values)) {
switch (relation.nature) {
case 'manyToOne':
const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models);
if (!_.isEmpty(relation) && _.isArray(values)) {
switch (relation.nature) {
case 'manyToOne': {
const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models);
const arrayOfPromises = _.map(values, function (value) {
const parameters = {};
const arrayOfPromises = _.map(values, function (value) {
const parameters = {};
_.set(parameters, PK, value);
_.set(parameters, 'relation', relation.via);
_.set(parameters, PK, value);
_.set(parameters, 'relation', relation.via);
return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [_.get(params, 'id') || null]);
});
return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [_.get(params, 'id') || null]);
});
Promise.all(arrayOfPromises)
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
break;
case 'manyToMany':
<%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().attach(values)
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
break;
default:
reject('Impossible to add relation on this type of relation');
return Promise.all(arrayOfPromises);
}
} else {
reject('Bad request');
case 'manyToMany': {
return <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().attach(values);
}
default:
return new Error('Impossible to add relation on this type of relation');
}
});
}
return new Error('Relationship Not Found');
},
/**
@ -167,108 +111,93 @@ module.exports = {
*/
editRelation: (params, values) => {
return new Promise((resolve, reject) => {
const relation = _.find(strapi.models.<%= subId || id %>.associations, {alias: params.relation});
if (!_.isEmpty(relation) && _.isArray(values)) {
switch (relation.nature) {
case 'oneWay':
case 'oneToOne':
case 'oneToMany':
case 'oneToMany': {
const data = _.set({}, params.relation, _.first(values) || null);
<%= globalID %>.forge(_.omit(params, 'relation')).save(data, {path: true})
.then(<%= subId || id %> => {
resolve();
})
.catch(err => {
reject(err);
});
break;
case 'manyToOne':
return <%= globalID %>.forge(_.omit(params, 'relation')).save(data, {path: true});
}
case 'manyToOne': {
const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models);
<%= globalID %>.forge(_.omit(params, 'relation')).fetch({
const results = await <%= globalID %>.forge(_.omit(params, 'relation')).fetch({
withRelated: _.get(params, 'relation')
})
.then(<%= subId || id %> => {
const data = <%= subId || id %>.toJSON() || {};
const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK));
const valuesToRemove = _.difference(currentValues, values);
});
const arrayOfPromises = _.map(valuesToRemove, value => {
const params = {};
// Remove relationship between records.
const data = results.toJSON() || {};
const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK));
const valuesToRemove = _.difference(currentValues, values);
_.set(params, PK, value);
_.set(params, 'relation', relation.via);
const arrayOfRemovePromises = _.map(valuesToRemove, value => {
const params = {};
return strapi.services[_.get(relation, relation.type)].editRelation(params, [null]);
});
_.set(params, PK, value);
_.set(params, 'relation', relation.via);
return Promise.all(arrayOfPromises);
})
.then(() => {
const arrayOfPromises = _.map(values, value => {
const params = {};
return strapi.services[_.get(relation, relation.type)].editRelation(params, [null]);
});
_.set(params, PK, value);
_.set(params, 'relation', relation.via);
await Promise.all(arrayOfRemovePromises);
return strapi.services[_.get(relation, relation.type)].editRelation(params, [_.get(params, 'id') || null]);
});
// Add relationship between records.
const arrayOfAddPromises = _.map(values, value => {
const params = {};
return Promise.all(arrayOfPromises);
})
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
break;
case 'manyToMany':
<%= globalID %>.forge(_.omit(params, 'relation')).fetch({
_.set(params, PK, value);
_.set(params, 'relation', relation.via);
return strapi.services[_.get(relation, relation.type)].editRelation(params, [_.get(params, 'id') || null]);
});
await Promise.all(arrayOfAddPromises);
return;
}
case 'manyToMany': {
const results = <%= globalID %>.forge(_.omit(params, 'relation')).fetch({
withRelated: _.get(params, 'relation')
})
.then(<%= subId || id %> => {
const data = <%= subId || id %>.toJSON() || {};
const PK = utils.getPK('<%= globalID %>', <%= globalID %>, strapi.models);
});
const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK));
const valuesToAdd = _.difference(_.map(values, o => {
return o.toString();
}), currentValues);
const data = results.toJSON() || {};
const PK = utils.getPK('<%= globalID %>', <%= globalID %>, strapi.models);
return <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().attach(valuesToAdd)
.then(function () {
return <%= subId || id %>;
})
})
.then(<%= subId || id %> => {
const data = <%= subId || id %>.toJSON() || {};
const PK = utils.getPK('<%= globalID %>', <%= globalID %>, strapi.models);
// Values to add
const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK));
const valuesToAdd = _.difference(_.map(values, o => {
return o.toString();
}), currentValues);
const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK));
const valuesToDrop = _.difference(currentValues, _.map(values, o => {
return o.toString();
}));
try {
await <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().attach(valuesToAdd);
} catch (err) {
return err;
}
return <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().detach(valuesToDrop);
})
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
break;
// Values to remove
const valuesToDrop = _.difference(currentValues, _.map(values, o => {
return o.toString();
}));
try {
await <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().detach(valuesToDrop);
} catch (err) {
return err;
}
return;
}
default:
reject('Impossible to update relation on this type of relation');
return new Error('Impossible to update relation on this type of relation');
}
} else {
reject('Bad request');
}
});
return new Error ('Relationship Not Found');
},
/**
@ -278,46 +207,30 @@ module.exports = {
*/
removeRelation: (params, values) => {
return new Promise((resolve, reject) => {
const relation = _.find(strapi.models.<%= subId || id %>.associations, {alias: params.relation});
const relation = _.find(strapi.models.<%= subId || id %>.associations, {alias: params.relation});
if (!_.isEmpty(relation) && _.isArray(values)) {
switch (relation.nature) {
case 'manyToOne':
const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models);
if (!_.isEmpty(relation) && _.isArray(values)) {
switch (relation.nature) {
case 'manyToOne':
const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models);
const arrayOfPromises = _.map(values, value => {
const parameters = {};
const arrayOfPromises = _.map(values, value => {
const parameters = {};
_.set(parameters, PK, value);
_.set(parameters, 'relation', relation.via);
_.set(parameters, PK, value);
_.set(parameters, 'relation', relation.via);
return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [null]);
});
return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [null]);
});
Promise.all(arrayOfPromises)
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
break;
case 'manyToMany':
<%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().detach(values)
.then(<%= subId || id %> => {
resolve(<%= subId || id %>);
})
.catch(err => {
reject(err);
});
break;
default:
reject('Impossible to delete relation on this type of relation');
}
} else {
reject('Bad request');
return Promise.all(arrayOfPromises);
case 'manyToMany':
return <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().detach(values);
default:
return new Error('Impossible to delete relation on this type of relation');
}
});
}
return new Error('Relationship Not Found');
}
};

View File

@ -28,7 +28,7 @@ module.exports = {
* Find primary key per ORM
*/
getPK: (collectionIdentity, collection, models) => {
getPK: function (collectionIdentity, collection, models) {
if (_.isString(collectionIdentity)) {
const ORM = this.getORM(collectionIdentity);
@ -50,7 +50,7 @@ module.exports = {
* Find primary key per ORM
*/
getCount: collectionIdentity => {
getCount: function (collectionIdentity) {
if (_.isString(collectionIdentity)) {
const ORM = this.getORM(collectionIdentity);
@ -214,7 +214,7 @@ module.exports = {
* Define associations key to models
*/
defineAssociations: (model, definition, association, key) => {
defineAssociations: function (model, definition, association, key) {
// Initialize associations object
if (definition.associations === undefined) {
definition.associations = [];

View File

@ -39,11 +39,13 @@ module.exports = async function (ctx, next) {
try {
await next();
if (_.get(ctx.body, 'isBoom')) {
ctx.throw(ctx.status);
if (_.get(ctx.body, 'isBoom') || _.isError(ctx.body)) {
ctx.throw();
}
} catch (error) {
strapi.log.error(error);
// Error object could be also in the context body...
strapi.log.error(ctx.body || error);
// Wrap error into a Boom's response
const formattedError = _.get(ctx.body, 'isBoom') ? ctx.body || error.message : Boom.wrap(error, error.status, ctx.body || error.message);
ctx.status = formattedError.output.statusCode || error.status || 500;