Added support for include relationship alias (as) and nested includes, fixed wrong joi json validation implementation inside parseInclude() function, fixed some associated routes resulted 404 because of prefix option
This commit is contained in:
71
src/utils.js
71
src/utils.js
@ -1,6 +1,7 @@
|
||||
import { omit, identity, toNumber, isString, isUndefined } from 'lodash';
|
||||
import { notImplemented } from 'boom';
|
||||
import joi from 'joi';
|
||||
import Promise from 'bluebird';
|
||||
|
||||
const sequelizeKeys = ['include', 'order', 'limit', 'offset'];
|
||||
|
||||
@ -9,7 +10,7 @@ const getModels = (request) => {
|
||||
const noRequestModels = !request.models;
|
||||
if (noGetDb && noRequestModels) {
|
||||
return notImplemented('`request.getDb` or `request.models` are not defined.'
|
||||
+ 'Be sure to load hapi-sequelize before hapi-sequelize-crud.');
|
||||
+ 'Be sure to load hapi-sequelize before hapi-sequelize-crud.');
|
||||
}
|
||||
|
||||
const { models } = noGetDb ? request : request.getDb();
|
||||
@ -17,41 +18,69 @@ const getModels = (request) => {
|
||||
return models;
|
||||
};
|
||||
|
||||
export const parseInclude = request => {
|
||||
export const parseInclude = async(request) => {
|
||||
if (typeof request.query.include === 'undefined') return [];
|
||||
|
||||
const include = Array.isArray(request.query.include)
|
||||
? request.query.include
|
||||
: [request.query.include]
|
||||
? request.query.include
|
||||
: [request.query.include]
|
||||
;
|
||||
|
||||
const models = getModels(request);
|
||||
if (models.isBoom) return models;
|
||||
|
||||
return include.map(b => {
|
||||
const getModelInstance = includeItem => {
|
||||
return new Promise(async(resolve) => {
|
||||
if (includeItem) {
|
||||
if (typeof includeItem !== 'object') {
|
||||
const singluarOrPluralMatch = Object.keys(models).find((modelName) => {
|
||||
const { _singular, _plural } = models[modelName];
|
||||
return _singular === includeItem || _plural === includeItem;
|
||||
});
|
||||
|
||||
if (singluarOrPluralMatch) {
|
||||
return resolve(models[singluarOrPluralMatch]);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof includeItem === 'string' && models.hasOwnProperty(includeItem)) {
|
||||
return resolve(models[includeItem]);
|
||||
} else if (typeof includeItem === 'object') {
|
||||
if (
|
||||
typeof includeItem.model === 'string' &&
|
||||
includeItem.model.length &&
|
||||
models.hasOwnProperty(includeItem.model)
|
||||
) {
|
||||
includeItem.model = models[includeItem.model];
|
||||
}
|
||||
if (includeItem.hasOwnProperty('include')) {
|
||||
includeItem.include = await getModelInstance(includeItem.include);
|
||||
return resolve(includeItem);
|
||||
} else {
|
||||
return resolve(includeItem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return resolve(includeItem);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const jsonValidation = joi.string().regex(/^\{.*?"model":.*?\}$/);
|
||||
const includes = include.map(async(b) => {
|
||||
let a = b;
|
||||
try {
|
||||
if (joi.string().regex(/^\{.*?"model":.*?\}$/)) {
|
||||
if (!jsonValidation.validate(a).error) {
|
||||
a = JSON.parse(b);
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
if (typeof a !== 'object') {
|
||||
const singluarOrPluralMatch = Object.keys(models).find((modelName) => {
|
||||
const { _singular, _plural } = models[modelName];
|
||||
return _singular === a || _plural === a;
|
||||
});
|
||||
|
||||
if (singluarOrPluralMatch) return models[singluarOrPluralMatch];
|
||||
}
|
||||
|
||||
if (typeof a === 'string') return models[a];
|
||||
|
||||
if (a && typeof a.model === 'string' && a.model.length) {
|
||||
a.model = models[a.model];
|
||||
}
|
||||
|
||||
return a;
|
||||
return getModelInstance(a);
|
||||
}).filter(identity);
|
||||
|
||||
return await Promise.all(includes);
|
||||
};
|
||||
|
||||
export const parseWhere = request => {
|
||||
|
Reference in New Issue
Block a user