graphql-compose-mongoose
Version:
Plugin for `graphql-compose` which derive a graphql types from a mongoose model.
154 lines (130 loc) • 4.94 kB
JavaScript
;
exports.__esModule = true;
exports.OPERATORS_FIELDNAME = undefined;
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
exports.addFilterOperators = addFilterOperators;
exports.processFilterOperators = processFilterOperators;
exports._prepareAndOrFilter = _prepareAndOrFilter;
exports._createOperatorsField = _createOperatorsField;
var _graphql = require('graphql-compose/lib/graphql');
var _utils = require('../../utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-use-before-define */
const availableOperators = ['gt', 'gte', 'lt', 'lte', 'ne', 'in[]', 'nin[]'];
const OPERATORS_FIELDNAME = exports.OPERATORS_FIELDNAME = '_operators';
function addFilterOperators(itc, model, opts) {
if (!{}.hasOwnProperty.call(opts, 'operators') || opts.operators !== false) {
_createOperatorsField(itc, `Operators${opts.filterTypeName || ''}`, model, opts.operators || {});
}
itc.addFields({
OR: [itc.getTypeNonNull()],
AND: [itc.getTypeNonNull()]
});
}
function processFilterOperators(filter, resolveParams) {
_prepareAndOrFilter(filter, resolveParams);
if (filter[OPERATORS_FIELDNAME]) {
const operatorFields = filter[OPERATORS_FIELDNAME];
Object.keys(operatorFields).forEach(fieldName => {
const fieldOperators = (0, _extends3.default)({}, operatorFields[fieldName]);
const criteria = {};
Object.keys(fieldOperators).forEach(operatorName => {
criteria[`$${operatorName}`] = fieldOperators[operatorName];
});
if (Object.keys(criteria).length > 0) {
// eslint-disable-next-line
resolveParams.query = resolveParams.query.where({
[fieldName]: criteria
});
}
});
}
}
function _prepareAndOrFilter(filter, resolveParams) {
/* eslint-disable no-param-reassign */
if (!filter.OR && !filter.AND) return;
const { OR, AND } = filter;
if (OR) {
const $or = OR.map(d => {
_prepareAndOrFilter(d);
return (0, _utils.toMongoDottedObject)(d);
});
if (resolveParams) {
resolveParams.query.where({ $or });
} else {
filter.$or = $or;
delete filter.OR;
}
}
if (AND) {
const $and = AND.map(d => {
_prepareAndOrFilter(d);
return (0, _utils.toMongoDottedObject)(d);
});
if (resolveParams) {
resolveParams.query.where({ $and });
} else {
filter.$and = $and;
delete filter.AND;
}
}
/* eslint-enable no-param-reassign */
}
function _createOperatorsField(itc, typeName, model, operatorsOpts) {
const operatorsITC = itc.constructor.schemaComposer.getOrCreateITC(typeName, tc => {
tc.setDescription('For performance reason this type contains only *indexed* fields.');
});
// if `opts.resolvers.[resolverName].filter.operators` is empty and not disabled via `false`
// then fill it up with indexed fields
const indexedFields = (0, _utils.getIndexedFieldNamesForGraphQL)(model);
if (operatorsOpts !== false && Object.keys(operatorsOpts).length === 0) {
indexedFields.forEach(fieldName => {
operatorsOpts[fieldName] = availableOperators; // eslint-disable-line
});
}
itc.getFieldNames().forEach(fieldName => {
if (operatorsOpts[fieldName] && operatorsOpts[fieldName] !== false) {
const fields = {};
let operators;
if (operatorsOpts[fieldName] && Array.isArray(operatorsOpts[fieldName])) {
operators = operatorsOpts[fieldName];
} else {
operators = availableOperators;
}
operators.forEach(operatorName => {
const fc = itc.getFieldConfig(fieldName);
// unwrap from GraphQLNonNull and GraphQLList, if present
const namedType = (0, _graphql.getNamedType)(fc.type);
if (namedType) {
if (operatorName.slice(-2) === '[]') {
// wrap with GraphQLList, if operator required this with `[]`
const newName = operatorName.slice(0, -2);
fields[newName] = (0, _extends3.default)({}, fc, {
type: [namedType]
});
} else {
fields[operatorName] = (0, _extends3.default)({}, fc, {
type: namedType
});
}
}
});
if (Object.keys(fields).length > 0) {
const operatorTypeName = `${(0, _utils.upperFirst)(fieldName)}${typeName}`;
const operatorITC = itc.constructor.schemaComposer.getOrCreateITC(operatorTypeName, tc => {
tc.setFields(fields);
});
operatorsITC.setField(fieldName, operatorITC);
}
}
});
// add to main filterITC if was added some fields
if (operatorsITC.getFieldNames().length > 0) {
itc.setField(OPERATORS_FIELDNAME, {
type: operatorsITC,
description: 'List of *indexed* fields that can be filtered via operators.'
});
}
return operatorsITC;
}