'use strict'; /** * <%= filename %> service * * @description: A set of functions similar to controller's actions to avoid code duplication. */ // Public dependencies. const _ = require('lodash'); // Strapi utilities. const utils = require('strapi-bookshelf/lib/utils/'); module.exports = { /** * Promise to fetch all <%= idPluralized %>. * * @return {Promise} */ fetchAll: (params) => { return <%= globalID %>.forge(params).query(params).fetchAll({ withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= id %>.associations, {autoPopulate: false}), 'alias')) }); }, /** * Promise to fetch a/an <%= id %>. * * @return {Promise} */ fetch: (params) => { return <%= globalID %>.forge(_.pick(params, 'id')).fetch({ withRelated: _.keys(_.groupBy(_.reject(strapi.models.<%= id %>.associations, {autoPopulate: false}), 'alias')) }); }, /** * Promise to add a/an <%= id %>. * * @return {Promise} */ add: (values) => { return <%= globalID %>.forge(values).save(); }, /** * Promise to edit a/an <%= id %>. * * @return {Promise} */ edit: (params, values) => { return <%= globalID %>.forge(params).save(values, {path: true}); }, /** * Promise to remove a/an <%= id %>. * * @return {Promise} */ remove: (params) => { return <%= globalID %>.forge(params).destroy(); }, /** * Add relation to a specific <%= id %> (only from a to-many relationships). * * @return {Object} */ addRelation: (params, values) => { const relation = _.find(strapi.models.<%= 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); const arrayOfPromises = _.map(values, function (value) { const parameters = {}; _.set(parameters, PK, value); _.set(parameters, 'relation', relation.via); return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [_.get(params, 'id') || null]); }); return Promise.all(arrayOfPromises); } 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'); }, /** * Edit relation to a specific <%= id %>. * * @return {Object} */ editRelation: (params, values) => { const relation = _.find(strapi.models.<%= id %>.associations, {alias: params.relation}); if (!_.isEmpty(relation) && _.isArray(values)) { switch (relation.nature) { case 'oneWay': case 'oneToOne': case 'oneToMany': { const data = _.set({}, params.relation, _.first(values) || null); return <%= globalID %>.forge(_.omit(params, 'relation')).save(data, {path: true}); } case 'manyToOne': { const PK = utils.getPK(_.get(relation, relation.type), undefined, strapi.models); const results = await <%= globalID %>.forge(_.omit(params, 'relation')).fetch({ withRelated: _.get(params, 'relation') }); // Remove relationship between records. const data = results.toJSON() || {}; const currentValues = _.keys(_.groupBy(_.get(data, _.get(params, 'relation')), PK)); const valuesToRemove = _.difference(currentValues, values); const arrayOfRemovePromises = _.map(valuesToRemove, value => { const params = {}; _.set(params, PK, value); _.set(params, 'relation', relation.via); return strapi.services[_.get(relation, relation.type)].editRelation(params, [null]); }); await Promise.all(arrayOfRemovePromises); // Add relationship between records. const arrayOfAddPromises = _.map(values, value => { const params = {}; _.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') }); const data = results.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); try { await <%= globalID %>.forge(_.omit(params, 'relation'))[params.relation]().attach(valuesToAdd); } catch (err) { return err; } // 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: return new Error('Impossible to update relation on this type of relation'); } } return new Error ('Relationship Not Found'); }, /** * Promise to remove a specific entry from a specific <%= id %> (only from a to-many relationships). * * @return {Promise} */ removeRelation: (params, values) => { const relation = _.find(strapi.models.<%= 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); const arrayOfPromises = _.map(values, value => { const parameters = {}; _.set(parameters, PK, value); _.set(parameters, 'relation', relation.via); return strapi.services[_.get(relation, relation.type)].editRelation(parameters, [null]); }); 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'); } };