2019-07-16 17:23:24 +02:00

273 lines
7.2 KiB
JavaScript

'use strict';
const _ = require('lodash');
/**
* A set of functions called "actions" for `ContentManager`
*/
const parseFormInput = value => {
try {
const parsed = JSON.parse(value);
// do not modify initial value if it is string except 'null'
if (typeof parsed !== 'string') {
value = parsed;
}
} catch (e) {
// Silent.
}
return _.isArray(value) ? value.map(parseFormInput) : value;
};
/* eslint-disable indent */
module.exports = {
fetchAll: async (params, query) => {
const { query: request, source, populate = [], ...filters } = query;
const queryFilter = !_.isEmpty(request)
? {
...filters, // Filters is an object containing the limit/sort and start
...request,
}
: filters;
// Find entries using `queries` system
return await strapi.plugins['content-manager']
.queries(params.model, source)
.find(queryFilter, populate);
},
search: async (params, query) => {
const { limit, skip, sort, source, _q, populate = [] } = query; // eslint-disable-line no-unused-vars
const filters = strapi.utils.models.convertParams(params.model, query);
// Find entries using `queries` system
return await strapi.plugins['content-manager']
.queries(params.model, source)
.search(
{
limit: limit || filters.limit,
skip: skip || filters.start || 0,
sort: sort || filters.sort,
search: _q,
},
populate
);
},
countSearch: async (params, query) => {
const { source, _q } = query;
return await strapi.plugins['content-manager']
.queries(params.model, source)
.countSearch({ search: _q });
},
count: async (params, query) => {
const { source, ...filters } = query;
return await strapi.plugins['content-manager']
.queries(params.model, source)
.count(filters);
},
fetch: async (params, source, populate, raw = true) => {
return await strapi.plugins['content-manager']
.queries(params.model, source)
.findOne(
{
id: params.id,
},
populate,
raw
);
},
async add(params, values, source) {
// Multipart/form-data.
if (values.hasOwnProperty('fields') && values.hasOwnProperty('files')) {
const files = values.files;
// Parse stringify JSON data.
const data = Object.keys(values.fields).reduce((acc, current) => {
acc[current] = parseFormInput(values.fields[current]);
return acc;
}, {});
// Update JSON fields.
const entry = await strapi.plugins['content-manager']
.queries(params.model, source)
.create(data);
// Then, request plugin upload.
if (strapi.plugins.upload && Object.keys(files).length > 0) {
// Upload new files and attach them to this entity.
await strapi.plugins.upload.services.upload.uploadToEntity(
{
id: entry.id || entry._id,
model: params.model,
},
files,
source
);
}
return entry;
}
// Create an entry using `queries` system
return await strapi.plugins['content-manager']
.queries(params.model, source)
.create(values);
},
async edit(params, values, source) {
// Multipart/form-data.
if (values.hasOwnProperty('fields') && values.hasOwnProperty('files')) {
// Silent recursive parser.
const files = values.files;
// set empty attributes if old values was cleared
_.difference(Object.keys(files), Object.keys(values.fields)).forEach(
attr => {
values.fields[attr] = [];
}
);
// Parse stringify JSON data.
const data = Object.keys(values.fields).reduce((acc, current) => {
acc[current] = parseFormInput(values.fields[current]);
return acc;
}, {});
// Update
const updatedEntity = await strapi.plugins['content-manager']
.queries(params.model, source)
.update({ id: params.id }, data);
// Then, request plugin upload.
if (strapi.plugins.upload) {
// Upload new files and attach them to this entity.
await strapi.plugins.upload.services.upload.uploadToEntity(
params,
files,
source
);
}
return updatedEntity;
}
// Raw JSON.
return strapi.plugins['content-manager']
.queries(params.model, source)
.update({ id: params.id }, values);
},
delete: async (params, { source }) => {
const query = strapi.plugins['content-manager'].queries(
params.model,
source
);
const primaryKey = query.primaryKey;
const response = await query.findOne({
id: params.id,
});
if (!response) {
throw `This resource doesn't exist.`;
}
params[primaryKey] = response[primaryKey];
params.values = Object.keys(response).reduce((acc, current) => {
const association = (
strapi.models[params.model] ||
strapi.admin.models[params.model] ||
strapi.plugins[source].models[params.model]
).associations.filter(x => x.alias === current)[0];
// Remove relationships.
if (association) {
acc[current] = _.isArray(response[current]) ? [] : null;
}
return acc;
}, {});
if (!_.isEmpty(params.values)) {
// Run update to remove all relationships.
await strapi.plugins['content-manager']
.queries(params.model, source)
.update(params);
}
// Delete an entry using `queries` system
return await strapi.plugins['content-manager']
.queries(params.model, source)
.delete({
id: params.id,
});
},
deleteMany: async (params, query) => {
const { source } = query;
const { model } = params;
const primaryKey = strapi.plugins['content-manager'].queries(model, source)
.primaryKey;
const toRemove = Object.keys(query).reduce((acc, curr) => {
if (curr !== 'source') {
return acc.concat([query[curr]]);
}
return acc;
}, []);
const filter = { [`${primaryKey}_in`]: toRemove };
const entries = await strapi.plugins['content-manager']
.queries(model, source)
.find(filter, null, true);
const associations = strapi.plugins['content-manager'].queries(
model,
source
).associations;
for (let i = 0; i < entries.length; ++i) {
const entry = entries[i];
associations.forEach(association => {
if (entry[association.alias]) {
switch (association.nature) {
case 'oneWay':
case 'oneToOne':
case 'manyToOne':
case 'oneToManyMorph':
entry[association.alias] = null;
break;
case 'oneToMany':
case 'manyToMany':
case 'manyToManyMorph':
entry[association.alias] = [];
break;
default:
}
}
});
await strapi.plugins['content-manager'].queries(model, source).update({
[primaryKey]: entry[primaryKey],
values: _.pick(entry, associations.map(a => a.alias)),
});
}
return strapi.plugins['content-manager'].queries(model, source).deleteMany({
[primaryKey]: toRemove,
});
},
};