.
This commit is contained in:
parent
81d214b50a
commit
1f6d27f220
@ -2,7 +2,7 @@
|
||||
|
||||
const httpStatus = require('http-status');
|
||||
const expressValidation = require('express-validation');
|
||||
const APIError = require('../utils/APIError');
|
||||
const APIError = require('./APIError');
|
||||
|
||||
/**
|
||||
* Error handler. Send stacktrace only during development
|
||||
|
||||
136
utils/index.js
136
utils/index.js
@ -1,136 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable import/order */
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable prefer-template */
|
||||
// Dependencies.
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { map } = require('async'); // eslint-disable-line import/order
|
||||
const { setWith, merge, get, difference, intersection, isObject, isFunction } = require('lodash');
|
||||
const os = require('os');
|
||||
const vm = require('vm');
|
||||
const fetch = require('node-fetch');
|
||||
const Buffer = require('buffer').Buffer;
|
||||
const crypto = require('crypto');
|
||||
|
||||
module.exports = {
|
||||
loadFile: function (url) {
|
||||
// Clear cache.
|
||||
delete require.cache[require.resolve(path.resolve(this.config.appPath, url))];
|
||||
// Require without cache.
|
||||
return require(path.resolve(this.config.appPath, url));
|
||||
},
|
||||
|
||||
setConfig: function (ctx, path, type, loader) {
|
||||
const objPath = type === 'optional' ?
|
||||
this.optionalPath(path) :
|
||||
this.aggregatePath(path);
|
||||
|
||||
// Load value.
|
||||
const value = loader(path);
|
||||
// Merge doesn't work for none-object value and function.
|
||||
const obj = isObject(value) && !isFunction(value) ? merge(get(ctx, objPath), value) : value;
|
||||
|
||||
// Assignation.
|
||||
return setWith(ctx, objPath, obj, Object);
|
||||
},
|
||||
|
||||
optionalPath: path => {
|
||||
return path
|
||||
.replace(/(\.settings|.json|.js)/g, '')
|
||||
.split('/')
|
||||
.slice(1, path.split('/').length - 1)
|
||||
.join('.')
|
||||
.toLowerCase();
|
||||
},
|
||||
|
||||
aggregatePath: path => {
|
||||
return path
|
||||
.replace(/(\.settings|.json|.js)/g, '')
|
||||
.split('/')
|
||||
.slice(1)
|
||||
.join('.')
|
||||
.toLowerCase();
|
||||
},
|
||||
|
||||
loadConfig: function (files, shouldBeAggregated = false) {
|
||||
const aggregate = files.filter(p => {
|
||||
if (shouldBeAggregated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (intersection(p.split('/').map(p => p.replace('.json', '')), ['environments', 'database', 'security', 'request', 'response', 'server']).length === 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
p.indexOf('config/functions') !== -1 ||
|
||||
p.indexOf('config/policies') !== -1 ||
|
||||
p.indexOf('config/locales') !== -1 ||
|
||||
p.indexOf('config/hook') !== -1 ||
|
||||
p.indexOf('config/middleware') !== -1 ||
|
||||
p.indexOf('config/language') !== -1 ||
|
||||
p.indexOf('config/queries') !== -1 ||
|
||||
p.indexOf('config/layout') !== -1
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
const optional = difference(files, aggregate);
|
||||
|
||||
return Promise.all([
|
||||
new Promise((resolve, reject) => {
|
||||
map(aggregate, p =>
|
||||
module.exports.setConfig(this, p, 'aggregate', this.loadFile)
|
||||
);
|
||||
|
||||
resolve();
|
||||
}),
|
||||
new Promise((resolve, reject) => {
|
||||
map(optional, p =>
|
||||
module.exports.setConfig(this, p, 'optional', this.loadFile)
|
||||
);
|
||||
|
||||
resolve();
|
||||
})
|
||||
]);
|
||||
},
|
||||
|
||||
/*usage: async function () {
|
||||
try {
|
||||
if (this.config.uuid) {
|
||||
const publicKey = fs.readFileSync(path.resolve(__dirname, 'resources', 'key.pub'));
|
||||
const options = {
|
||||
timeout: 1500
|
||||
};
|
||||
|
||||
const [usage, signedHash, required] = await Promise.all([
|
||||
fetch('https://strapi.io/assets/images/usage.gif', options),
|
||||
fetch('https://strapi.io/hash.txt', options),
|
||||
fetch('https://strapi.io/required.txt', options)
|
||||
]).catch(err => {});
|
||||
|
||||
if (usage.status === 200 && signedHash.status === 200) {
|
||||
const code = Buffer.from(await usage.text(), 'base64').toString();
|
||||
const hash = crypto.createHash('sha512').update(code).digest('hex');
|
||||
const dependencies = Buffer.from(await required.text(), 'base64').toString();
|
||||
|
||||
const verifier = crypto.createVerify('RSA-SHA256').update(hash);
|
||||
|
||||
if (verifier.verify(publicKey, await signedHash.text(), 'hex')) {
|
||||
return new Promise(resolve => {
|
||||
vm.runInNewContext(code)(this.config.uuid, exposer(dependencies), resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Silent.
|
||||
}
|
||||
},*/
|
||||
|
||||
};
|
||||
509
utils/models.js
509
utils/models.js
@ -1,509 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core
|
||||
const path = require('path');
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
// Following this discussion https://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric this function is the best implem to determine if a value is a valid number candidate
|
||||
const isNumeric = (value) => {
|
||||
return !_.isObject(value) && !isNaN(parseFloat(value)) && isFinite(value);
|
||||
};
|
||||
|
||||
/* eslint-disable prefer-template */
|
||||
/*
|
||||
* Set of utils for models
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Initialize to prevent some mistakes
|
||||
*/
|
||||
|
||||
initialize: cb => {
|
||||
cb();
|
||||
},
|
||||
|
||||
/**
|
||||
* Find primary key per ORM
|
||||
*/
|
||||
|
||||
getPK: function (collectionIdentity, collection, models) {
|
||||
if (_.isString(collectionIdentity)) {
|
||||
const ORM = this.getORM(collectionIdentity);
|
||||
try {
|
||||
const GraphQLFunctions = require(path.resolve(strapi.config.appPath, 'node_modules', 'strapi-' + ORM, 'lib', 'utils'));
|
||||
|
||||
if (!_.isUndefined(GraphQLFunctions)) {
|
||||
return GraphQLFunctions.getPK(collectionIdentity, collection, models || strapi.models);
|
||||
}
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the value based on the primary key
|
||||
*/
|
||||
|
||||
getValuePrimaryKey: (value, defaultKey) => {
|
||||
return value[defaultKey] || value.id || value._id;
|
||||
},
|
||||
|
||||
/**
|
||||
* Find primary key per ORM
|
||||
*/
|
||||
|
||||
getCount: function (collectionIdentity) {
|
||||
if (_.isString(collectionIdentity)) {
|
||||
const ORM = this.getORM(collectionIdentity);
|
||||
|
||||
try {
|
||||
const ORMFunctions = require(path.resolve(strapi.config.appPath, 'node_modules', 'strapi-' + ORM, 'lib', 'utils'));
|
||||
|
||||
if (!_.isUndefined(ORMFunctions)) {
|
||||
return ORMFunctions.getCount(collectionIdentity);
|
||||
}
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Find relation nature with verbose
|
||||
*/
|
||||
|
||||
getNature: (association, key, models, currentModelName) => {
|
||||
try {
|
||||
const types = {
|
||||
current: '',
|
||||
other: ''
|
||||
};
|
||||
|
||||
if (_.isUndefined(models)) {
|
||||
models = association.plugin ? strapi.plugins[association.plugin].models : strapi.models;
|
||||
}
|
||||
|
||||
if ((association.hasOwnProperty('collection') && association.collection === '*') || (association.hasOwnProperty('model') && association.model === '*')) {
|
||||
if (association.model) {
|
||||
types.current = 'morphToD';
|
||||
} else {
|
||||
types.current = 'morphTo';
|
||||
}
|
||||
|
||||
const flattenedPluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
Object.keys(strapi.plugins[current].models).forEach((model) => {
|
||||
acc[`${current}_${model}`] = strapi.plugins[current].models[model];
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const allModels = _.merge({}, strapi.models, flattenedPluginsModels);
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(allModels, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.model === currentModelName) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'model';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('collection')) {
|
||||
const relatedAttribute = models[association.collection].attributes[association.via];
|
||||
|
||||
if (!relatedAttribute) {
|
||||
throw new Error(`The attribute \`${association.via}\` is missing in the model ${_.upperFirst(association.collection)} ${association.plugin ? '(plugin - ' + association.plugin + ')' : '' }`);
|
||||
}
|
||||
|
||||
types.current = 'collection';
|
||||
|
||||
if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.collection !== '*' && relatedAttribute.hasOwnProperty('via')) {
|
||||
types.other = 'collection';
|
||||
} else if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.collection !== '*' && !relatedAttribute.hasOwnProperty('via')) {
|
||||
types.other = 'collectionD';
|
||||
} else if (relatedAttribute.hasOwnProperty('model') && relatedAttribute.model !== '*') {
|
||||
types.other = 'model';
|
||||
} else if (relatedAttribute.hasOwnProperty('collection') || relatedAttribute.hasOwnProperty('model')) {
|
||||
types.other = 'morphTo';
|
||||
}
|
||||
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('model')) {
|
||||
types.current = 'modelD';
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
const model = models[association.model];
|
||||
const attribute = model.attributes[association.via];
|
||||
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection') && attribute.collection !== '*') {
|
||||
types.other = 'collection';
|
||||
} else if (attribute.hasOwnProperty('model') && attribute.model !== '*') {
|
||||
types.other = 'model';
|
||||
} else if (attribute.hasOwnProperty('collection') || attribute.hasOwnProperty('model')) {
|
||||
types.other = 'morphTo';
|
||||
}
|
||||
} else if (association.hasOwnProperty('model')) {
|
||||
types.current = 'model';
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(models, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'modelD';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (association.hasOwnProperty('collection')) {
|
||||
types.current = 'collectionD';
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(models, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
types.other = 'modelD';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (types.current === 'collection' && types.other === 'morphTo') {
|
||||
return {
|
||||
nature: 'manyToManyMorph',
|
||||
verbose: 'morphMany'
|
||||
};
|
||||
} else if (types.current === 'collection' && types.other === 'morphToD') {
|
||||
return {
|
||||
nature: 'manyToOneMorph',
|
||||
verbose: 'morphMany'
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'morphTo') {
|
||||
return {
|
||||
nature: 'oneToManyMorph',
|
||||
verbose: 'morphOne'
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'morphToD') {
|
||||
return {
|
||||
nature: 'oneToOneMorph',
|
||||
verbose: 'morphOne'
|
||||
};
|
||||
} else if (types.current === 'morphToD' && types.other === 'collection') {
|
||||
return {
|
||||
nature: 'oneMorphToMany',
|
||||
verbose: 'belongsToMorph'
|
||||
};
|
||||
} else if (types.current === 'morphToD' && types.other === 'model') {
|
||||
return {
|
||||
nature: 'oneMorphToOne',
|
||||
verbose: 'belongsToMorph'
|
||||
};
|
||||
} else if (types.current === 'morphTo' && (types.other === 'model' || association.hasOwnProperty('model'))) {
|
||||
return {
|
||||
nature: 'manyMorphToOne',
|
||||
verbose: 'belongsToManyMorph'
|
||||
};
|
||||
} else if (types.current === 'morphTo' && (types.other === 'collection' || association.hasOwnProperty('collection'))) {
|
||||
return {
|
||||
nature: 'manyMorphToMany',
|
||||
verbose: 'belongsToManyMorph'
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'model') {
|
||||
return {
|
||||
nature: 'oneToOne',
|
||||
verbose: 'belongsTo'
|
||||
};
|
||||
} else if (types.current === 'model' && types.other === 'modelD') {
|
||||
return {
|
||||
nature: 'oneToOne',
|
||||
verbose: 'hasOne'
|
||||
};
|
||||
} else if ((types.current === 'model' || types.current === 'modelD') && types.other === 'collection') {
|
||||
return {
|
||||
nature: 'manyToOne',
|
||||
verbose: 'belongsTo'
|
||||
};
|
||||
} else if (types.current === 'modelD' && types.other === 'collection') {
|
||||
return {
|
||||
nature: 'oneToMany',
|
||||
verbose: 'hasMany'
|
||||
};
|
||||
} else if (types.current === 'collection' && types.other === 'model') {
|
||||
return {
|
||||
nature: 'oneToMany',
|
||||
verbose: 'hasMany'
|
||||
};
|
||||
} else if (types.current === 'collection' && types.other === 'collection') {
|
||||
return {
|
||||
nature: 'manyToMany',
|
||||
verbose: 'belongsToMany'
|
||||
};
|
||||
} else if (types.current === 'collectionD' && types.other === 'collection' || types.current === 'collection' && types.other === 'collectionD') {
|
||||
return {
|
||||
nature: 'manyToMany',
|
||||
verbose: 'belongsToMany'
|
||||
};
|
||||
} else if (types.current === 'collectionD' && types.other === '') {
|
||||
return {
|
||||
nature: 'manyWay',
|
||||
verbose: 'belongsToMany'
|
||||
};
|
||||
} else if (types.current === 'model' && types.other === '') {
|
||||
return {
|
||||
nature: 'oneWay',
|
||||
verbose: 'belongsTo'
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
} catch (e) {
|
||||
strapi.log.error(`Something went wrong in the model \`${_.upperFirst(currentModelName)}\` with the attribute \`${key}\``);
|
||||
strapi.log.error(e);
|
||||
strapi.stop();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return ORM used for this collection.
|
||||
*/
|
||||
|
||||
getORM: collectionIdentity => {
|
||||
return _.get(strapi.models, collectionIdentity.toLowerCase() + '.orm');
|
||||
},
|
||||
|
||||
/**
|
||||
* Define associations key to models
|
||||
*/
|
||||
|
||||
defineAssociations: function (model, definition, association, key) {
|
||||
try {
|
||||
// Initialize associations object
|
||||
if (definition.associations === undefined) {
|
||||
definition.associations = [];
|
||||
}
|
||||
|
||||
// Exclude non-relational attribute
|
||||
if (!association.hasOwnProperty('collection') && !association.hasOwnProperty('model')) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Get relation nature
|
||||
let details;
|
||||
const globalName = association.model || association.collection || '';
|
||||
const infos = this.getNature(association, key, undefined, model.toLowerCase());
|
||||
|
||||
if (globalName !== '*') {
|
||||
details = association.plugin ?
|
||||
_.get(strapi.plugins, `${association.plugin}.models.${globalName}.attributes.${association.via}`, {}):
|
||||
_.get(strapi.models, `${globalName}.attributes.${association.via}`, {});
|
||||
}
|
||||
|
||||
// Build associations object
|
||||
if (association.hasOwnProperty('collection') && association.collection !== '*') {
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: 'collection',
|
||||
collection: association.collection,
|
||||
via: association.via || undefined,
|
||||
nature: infos.nature,
|
||||
autoPopulate: _.get(association, 'autoPopulate', true),
|
||||
dominant: details.dominant !== true,
|
||||
plugin: association.plugin || undefined,
|
||||
filter: details.filter,
|
||||
});
|
||||
} else if (association.hasOwnProperty('model') && association.model !== '*') {
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: 'model',
|
||||
model: association.model,
|
||||
via: association.via || undefined,
|
||||
nature: infos.nature,
|
||||
autoPopulate: _.get(association, 'autoPopulate', true),
|
||||
dominant: details.dominant !== true,
|
||||
plugin: association.plugin || undefined,
|
||||
filter: details.filter,
|
||||
});
|
||||
} else if (association.hasOwnProperty('collection') || association.hasOwnProperty('model')) {
|
||||
const pluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
Object.keys(strapi.plugins[current].models).forEach((entity) => {
|
||||
Object.keys(strapi.plugins[current].models[entity].attributes).forEach((attribute) => {
|
||||
const attr = strapi.plugins[current].models[entity].attributes[attribute];
|
||||
|
||||
if (
|
||||
(attr.collection || attr.model || '').toLowerCase() === model.toLowerCase() &&
|
||||
strapi.plugins[current].models[entity].globalId !== definition.globalId
|
||||
) {
|
||||
acc.push(strapi.plugins[current].models[entity].globalId);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const appModels = Object.keys(strapi.models).reduce((acc, entity) => {
|
||||
Object.keys(strapi.models[entity].attributes).forEach((attribute) => {
|
||||
const attr = strapi.models[entity].attributes[attribute];
|
||||
|
||||
if (
|
||||
(attr.collection || attr.model || '').toLowerCase() === model.toLowerCase() &&
|
||||
strapi.models[entity].globalId !== definition.globalId
|
||||
) {
|
||||
acc.push(strapi.models[entity].globalId);
|
||||
}
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const models = _.uniq(appModels.concat(pluginsModels));
|
||||
|
||||
definition.associations.push({
|
||||
alias: key,
|
||||
type: association.model ? 'model' : 'collection',
|
||||
related: models,
|
||||
nature: infos.nature,
|
||||
autoPopulate: _.get(association, 'autoPopulate', true),
|
||||
filter: association.filter,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
strapi.log.error(`Something went wrong in the model \`${_.upperFirst(model)}\` with the attribute \`${key}\``);
|
||||
strapi.log.error(e);
|
||||
strapi.stop();
|
||||
}
|
||||
},
|
||||
|
||||
getVia: (attribute, association) => {
|
||||
return _.findKey(strapi.models[association.model || association.collection].attributes, {via: attribute});
|
||||
},
|
||||
|
||||
convertParams: (entity, params) => {
|
||||
if (!entity) {
|
||||
throw new Error('You can\'t call the convert params method without passing the model\'s name as a first argument.');
|
||||
}
|
||||
|
||||
// Remove the source params (that can be sent from the ctm plugin) since it is not a filter
|
||||
if (params.source) {
|
||||
delete params.source;
|
||||
}
|
||||
|
||||
const model = entity.toLowerCase();
|
||||
|
||||
const models = _.assign(_.clone(strapi.models), Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
_.assign(acc, _.get(strapi.plugins[current], ['models'], {}));
|
||||
return acc;
|
||||
}, {}));
|
||||
|
||||
if (!models.hasOwnProperty(model)) {
|
||||
return this.log.error(`The model ${model} can't be found.`);
|
||||
}
|
||||
|
||||
const client = models[model].client;
|
||||
const connector = models[model].orm;
|
||||
|
||||
if (!connector) {
|
||||
throw new Error(`Impossible to determine the ORM used for the model ${model}.`);
|
||||
}
|
||||
|
||||
const convertor = strapi.hook[connector].load().getQueryParams;
|
||||
const convertParams = {
|
||||
where: {},
|
||||
sort: '',
|
||||
start: 0,
|
||||
limit: 100
|
||||
};
|
||||
|
||||
_.forEach(params, (value, key) => {
|
||||
let result;
|
||||
let formattedValue;
|
||||
let modelAttributes = models[model]['attributes'];
|
||||
let fieldType;
|
||||
// Get the field type to later check if it's a string before number conversion
|
||||
if (modelAttributes[key]) {
|
||||
fieldType = modelAttributes[key]['type'];
|
||||
} else {
|
||||
// Remove the filter keyword at the end
|
||||
let splitKey = key.split('_').slice(0,-1);
|
||||
splitKey = splitKey.join('_');
|
||||
if (modelAttributes[splitKey]) {
|
||||
fieldType = modelAttributes[splitKey]['type'];
|
||||
}
|
||||
}
|
||||
// Check if the value is a valid candidate to be converted to a number value
|
||||
if (fieldType !== 'string') {
|
||||
formattedValue = isNumeric(value)
|
||||
? _.toNumber(value)
|
||||
: value;
|
||||
} else {
|
||||
formattedValue = value;
|
||||
}
|
||||
|
||||
if (_.includes(['_start', '_limit', '_populate'], key)) {
|
||||
result = convertor(formattedValue, key);
|
||||
} else if (key === '_sort') {
|
||||
const [attr, order = 'ASC'] = formattedValue.split(':');
|
||||
result = convertor(order, key, attr);
|
||||
} else {
|
||||
const suffix = key.split('_');
|
||||
// Mysql stores boolean as 1 or 0
|
||||
if (client === 'mysql' && _.get(models, [model, 'attributes', suffix, 'type']) === 'boolean') {
|
||||
formattedValue = value.toString() === 'true' ? '1' : '0';
|
||||
}
|
||||
|
||||
let type;
|
||||
|
||||
if (_.includes(['ne', 'lt', 'gt', 'lte', 'gte', 'contains', 'containss', 'in', 'nin'], _.last(suffix))) {
|
||||
type = `_${_.last(suffix)}`;
|
||||
key = _.dropRight(suffix).join('_');
|
||||
} else {
|
||||
type = '=';
|
||||
}
|
||||
|
||||
result = convertor(formattedValue, type, key);
|
||||
}
|
||||
|
||||
_.set(convertParams, result.key, result.value);
|
||||
});
|
||||
|
||||
return convertParams;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user