graphql-compose-mongoose
Version:
Plugin for `graphql-compose` which derive a graphql types from a mongoose model.
98 lines (78 loc) • 3.15 kB
JavaScript
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
/* eslint-disable no-use-before-define */
import GraphQLMongoID from '../../types/mongoid';
import { isObject, toMongoDottedObject, getIndexedFieldNamesForGraphQL } from '../../utils';
import { addFilterOperators, processFilterOperators } from './filterOperators';
export const filterHelperArgs = (typeComposer, model, opts) => {
if (!typeComposer || typeComposer.constructor.name !== 'TypeComposer') {
throw new Error('First arg for filterHelperArgs() should be instance of TypeComposer.');
}
if (!model || !model.modelName || !model.schema) {
throw new Error('Second arg for filterHelperArgs() should be instance of MongooseModel.');
}
if (!opts || !opts.filterTypeName) {
throw new Error('You should provide non-empty `filterTypeName` in options.');
}
const removeFields = [];
if (opts.removeFields) {
if (Array.isArray(opts.removeFields)) {
removeFields.push(...opts.removeFields);
} else {
removeFields.push(opts.removeFields);
}
}
if (opts.onlyIndexed) {
const indexedFieldNames = getIndexedFieldNamesForGraphQL(model);
Object.keys(typeComposer.getFields()).forEach(fieldName => {
if (indexedFieldNames.indexOf(fieldName) === -1) {
removeFields.push(fieldName);
}
});
}
const filterTypeName = opts.filterTypeName;
const itc = typeComposer.getInputTypeComposer().clone(filterTypeName);
itc.addFields({
_ids: [GraphQLMongoID]
});
itc.removeField(removeFields);
if (opts.requiredFields) {
itc.makeRequired(opts.requiredFields);
}
if (itc.getFieldNames().length === 0) {
return {};
}
addFilterOperators(itc, model, opts);
return {
filter: {
type: opts.isRequired ? itc.getTypeNonNull() : itc.getType(),
description: opts.onlyIndexed ? 'Filter only by indexed fields' : 'Filter by fields'
}
};
};
export function filterHelper(resolveParams) {
const filter = resolveParams.args && resolveParams.args.filter;
if (filter && typeof filter === 'object' && Object.keys(filter).length > 0) {
const modelFields = resolveParams.query.schema.paths;
const { _ids } = filter,
filterFields = _objectWithoutProperties(filter, ['_ids']);
if (_ids && Array.isArray(_ids)) {
// eslint-disable-next-line
resolveParams.query = resolveParams.query.where({ _id: { $in: _ids } });
}
const clearedFilter = {};
Object.keys(filterFields).forEach(key => {
if (modelFields[key]) {
clearedFilter[key] = filterFields[key];
}
});
if (Object.keys(clearedFilter).length > 0) {
// eslint-disable-next-line
resolveParams.query = resolveParams.query.where(toMongoDottedObject(clearedFilter));
}
processFilterOperators(filter, resolveParams);
}
if (isObject(resolveParams.rawQuery)) {
// eslint-disable-next-line
resolveParams.query = resolveParams.query.where(resolveParams.rawQuery);
}
}