299 lines
8.1 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Module dependencies
*/
// Public node modules.
const _ = require('lodash');
// Node.js core
const path = require('path');
/*
* Set of utils for models
*/
module.exports = {
2016-07-05 14:13:35 +02:00
/**
* Initialize to prevent some mistakes
*/
initialize: cb => {
cb();
},
2016-03-17 15:05:47 +01:00
/**
* Find primary key per ORM
*/
getPK: function (collectionIdentity, collection, models) {
2016-03-17 15:05:47 +01:00
if (_.isString(collectionIdentity)) {
const ORM = this.getORM(collectionIdentity);
2016-07-06 15:51:52 +02:00
try {
const GraphQLFunctions = require(path.resolve(strapi.config.appPath, 'node_modules', 'strapi-' + ORM, 'lib', 'utils'));
2016-07-06 15:51:52 +02:00
if (!_.isUndefined(GraphQLFunctions)) {
return GraphQLFunctions.getPK(collectionIdentity, collection, models || strapi.models);
}
} catch (err) {
return undefined;
2016-03-17 15:05:47 +01:00
}
}
return undefined;
},
/**
* Find primary key per ORM
*/
getCount: function (collectionIdentity) {
2016-03-17 15:05:47 +01:00
if (_.isString(collectionIdentity)) {
const ORM = this.getORM(collectionIdentity);
2016-07-06 15:51:52 +02:00
try {
const ORMFunctions = require(path.resolve(strapi.config.appPath, 'node_modules', 'strapi-' + ORM, 'lib', 'utils'));
2016-07-06 15:51:52 +02:00
if (!_.isUndefined(ORMFunctions)) {
return ORMFunctions.getCount(collectionIdentity);
}
} catch (err) {
return undefined;
2016-03-17 15:05:47 +01:00
}
}
return undefined;
},
/**
* Find relation nature with verbose
*/
getNature: (association, key, models) => {
const types = {
current: '',
other: ''
};
2016-04-19 17:29:19 +02:00
if (_.isUndefined(models)) {
models = global['strapi'].models;
}
if (association.hasOwnProperty('via') && association.hasOwnProperty('collection')) {
const relatedAttribute = models[association.collection].attributes[association.via];
types.current = 'collection';
2016-08-08 11:12:09 +02:00
if (relatedAttribute.hasOwnProperty('collection') && relatedAttribute.hasOwnProperty('via')) {
types.other = 'collection';
2016-08-08 11:12:09 +02:00
} else if (relatedAttribute.hasOwnProperty('collection') && !relatedAttribute.hasOwnProperty('via')) {
types.other = 'collectionD';
} else if (relatedAttribute.hasOwnProperty('model')) {
types.other = 'model';
}
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('model')) {
types.current = 'modelD';
// We have to find if they are a model linked to this key
2016-07-06 15:51:52 +02:00
_.forIn(models, model => {
_.forIn(model.attributes, attribute => {
if (attribute.hasOwnProperty('via') && attribute.via === key && 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('model')) {
types.current = 'model';
2016-08-08 11:12:09 +02:00
// 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
2016-07-06 15:51:52 +02:00
_.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 === '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.other === 'collection') {
return {
nature: 'oneToMany',
verbose: 'belongsTo'
};
} else if (types.current === 'collection' && types.other === 'model') {
return {
nature: 'manyToOne',
verbose: 'hasMany'
};
} else if (types.current === 'collection' && types.other === 'collection') {
return {
nature: 'manyToMany',
verbose: 'belongsToMany'
};
2016-08-08 11:12:09 +02:00
} 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;
},
/**
* 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) {
// Initialize associations object
2016-08-19 13:37:33 +02:00
if (definition.associations === undefined) {
definition.associations = [];
}
// Exclude non-relational attribute
if (!association.hasOwnProperty('collection') && !association.hasOwnProperty('model')) {
return undefined;
}
// Get relation nature
const infos = this.getNature(association, key);
// Build associations object
if (association.hasOwnProperty('collection')) {
definition.associations.push({
alias: key,
type: 'collection',
collection: association.collection,
via: association.via || undefined,
nature: infos.nature,
autoPopulate: (_.get(association, 'autoPopulate') || _.get(strapi.config, 'jsonapi.enabled')) === true
});
} else if (association.hasOwnProperty('model')) {
definition.associations.push({
alias: key,
type: 'model',
model: association.model,
via: association.via || undefined,
nature: infos.nature,
autoPopulate: (_.get(association, 'autoPopulate') || _.get(strapi.config, 'jsonapi.enabled')) === true
});
}
2016-08-08 11:12:09 +02:00
},
getVia: (attribute, association) => {
2016-09-28 11:42:26 +02:00
return _.findKey(strapi.models[association.model || association.collection].attributes, {via: attribute});
2017-09-12 17:58:31 +02:00
},
convertParams: (model, params) => {
if (!model) {
return this.log.error(`You can't call the convert params method without passing the model as a first argument.`);
}
const convertor = strapi.hook[model.orm].load().getQueryParams;
const convertParams = {
where: {},
sort: {},
start: 0,
limit: 100
};
_.forEach(params, (value, key) => {
let result;
if (_.includes(['_start', '_limit'], key)) {
result = convertor(value, key);
} else if (key === '_sort') {
const [attr, order] = value.split(':');
result = convertor(order, key, attr);
} else {
const suffix = key.split('_');
let type;
if (_.includes(['ne', 'lt', 'gt', 'lte', 'gte'], _.last(suffix))) {
type = `_${_.last(suffix)}`;
key = _.dropRight(suffix).join('_');
} else {
type = '=';
}
result = convertor(value, type, key);
}
_.set(convertParams, result.key, result.value);
});
return convertParams;
}
};