uses find instead of findByID in GraphQL relationships to enable further filtering
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { NotFound } = require('../../errors');
|
||||
|
||||
const findByID = async (options) => {
|
||||
@@ -10,8 +9,6 @@ const findByID = async (options) => {
|
||||
depth, locale, fallbackLocale, model, id,
|
||||
} = options;
|
||||
|
||||
const hasMultipleIDs = Array.isArray(id);
|
||||
|
||||
if (depth && depth !== '0') {
|
||||
mongooseOptions.options.autopopulate = {
|
||||
maxDepth: parseInt(depth, 10),
|
||||
@@ -20,29 +17,12 @@ const findByID = async (options) => {
|
||||
mongooseOptions.options.autopopulate = false;
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
try {
|
||||
// Await pre find hook here
|
||||
|
||||
if (hasMultipleIDs) {
|
||||
result = await model.find({
|
||||
_id: {
|
||||
$in: id.map(docId => mongoose.Types.ObjectId(docId)),
|
||||
},
|
||||
}, {}, mongooseOptions);
|
||||
} else {
|
||||
result = await model.findOne({ _id: id }, {}, mongooseOptions);
|
||||
}
|
||||
const result = await model.findOne({ _id: id }, {}, mongooseOptions);
|
||||
|
||||
if (!result || (result && result.length === 0)) throw new NotFound();
|
||||
|
||||
if (hasMultipleIDs) {
|
||||
return result.map((doc) => {
|
||||
if (locale && doc.setLocale) doc.setLocale(locale, fallbackLocale);
|
||||
return doc.toJSON({ virtuals: true });
|
||||
});
|
||||
}
|
||||
if (!result) throw new NotFound();
|
||||
|
||||
if (locale && result.setLocale) {
|
||||
result.setLocale(locale, fallbackLocale);
|
||||
|
||||
@@ -11,6 +11,7 @@ const graphQLHTTP = require('express-graphql');
|
||||
const getBuildObjectType = require('./schema/getBuildObjectType');
|
||||
const buildWhereInputType = require('./schema/buildWhereInputType');
|
||||
const buildLocaleInputType = require('./schema/buildLocaleInputType');
|
||||
const buildPaginatedListType = require('./schema/buildPaginatedListType');
|
||||
const buildFallbackLocaleInputType = require('./schema/buildFallbackLocaleInputType');
|
||||
const formatName = require('./utilities/formatName');
|
||||
const { getFind, getFindByID } = require('../collections/graphql/resolvers');
|
||||
@@ -131,24 +132,7 @@ class GraphQL {
|
||||
};
|
||||
|
||||
this.Query.fields[pluralLabel] = {
|
||||
type: new GraphQLObjectType({
|
||||
name: pluralLabel,
|
||||
fields: {
|
||||
docs: {
|
||||
type: new GraphQLList(collection.graphQLType),
|
||||
},
|
||||
totalDocs: { type: GraphQLInt },
|
||||
offset: { type: GraphQLInt },
|
||||
limit: { type: GraphQLInt },
|
||||
totalPages: { type: GraphQLInt },
|
||||
page: { type: GraphQLInt },
|
||||
pagingCounter: { type: GraphQLInt },
|
||||
hasPrevPage: { type: GraphQLBoolean },
|
||||
hasNextPage: { type: GraphQLBoolean },
|
||||
prevPage: { type: GraphQLBoolean },
|
||||
nextPage: { type: GraphQLBoolean },
|
||||
},
|
||||
}),
|
||||
type: buildPaginatedListType(pluralLabel, collection.graphQLType),
|
||||
args: {
|
||||
where: {
|
||||
type: collection.graphQLWhereInputType,
|
||||
|
||||
26
src/graphql/schema/buildPaginatedListType.js
Normal file
26
src/graphql/schema/buildPaginatedListType.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const {
|
||||
GraphQLList, GraphQLObjectType, GraphQLInt, GraphQLBoolean,
|
||||
} = require('graphql');
|
||||
|
||||
const buildPaginatedListType = (name, docType) => {
|
||||
return new GraphQLObjectType({
|
||||
name,
|
||||
fields: {
|
||||
docs: {
|
||||
type: new GraphQLList(docType),
|
||||
},
|
||||
totalDocs: { type: GraphQLInt },
|
||||
offset: { type: GraphQLInt },
|
||||
limit: { type: GraphQLInt },
|
||||
totalPages: { type: GraphQLInt },
|
||||
page: { type: GraphQLInt },
|
||||
pagingCounter: { type: GraphQLInt },
|
||||
hasPrevPage: { type: GraphQLBoolean },
|
||||
hasNextPage: { type: GraphQLBoolean },
|
||||
prevPage: { type: GraphQLBoolean },
|
||||
nextPage: { type: GraphQLBoolean },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = buildPaginatedListType;
|
||||
@@ -14,7 +14,7 @@ const {
|
||||
const formatName = require('../utilities/formatName');
|
||||
const combineParentName = require('../utilities/combineParentName');
|
||||
const withNullableType = require('./withNullableType');
|
||||
const findByID = require('../../collections/queries/findByID');
|
||||
const find = require('../../collections/queries/find');
|
||||
|
||||
function getBuildObjectType(graphQLContext) {
|
||||
const buildObjectType = (name, fields, parentName) => {
|
||||
@@ -111,14 +111,22 @@ function getBuildObjectType(graphQLContext) {
|
||||
id = relatedDoc.value;
|
||||
}
|
||||
|
||||
const result = await findByID({
|
||||
const result = await find({
|
||||
model: graphQLContext.collections[relatedCollectionSlug].model,
|
||||
id,
|
||||
query: {
|
||||
where: {
|
||||
_id: {
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
},
|
||||
locale,
|
||||
fallbackLocale,
|
||||
});
|
||||
|
||||
results.push(result);
|
||||
if (result.docs.length === 1) {
|
||||
results.push(result.docs[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,15 +139,25 @@ function getBuildObjectType(graphQLContext) {
|
||||
if (id) {
|
||||
id = id.toString();
|
||||
|
||||
const relatedDocument = await findByID({
|
||||
const relatedDocument = await find({
|
||||
model: graphQLContext.collections[relatedCollectionSlug].model,
|
||||
id,
|
||||
query: {
|
||||
where: {
|
||||
_id: {
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
},
|
||||
locale,
|
||||
fallbackLocale,
|
||||
});
|
||||
|
||||
return relatedDocument;
|
||||
if (relatedDocument.docs[0]) return relatedDocument.docs[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,6 +11,16 @@ function addSearchParam(key, value, searchParams) {
|
||||
};
|
||||
}
|
||||
|
||||
function convertArrayFromCommaDelineated(input) {
|
||||
if (Array.isArray(input)) return input;
|
||||
|
||||
if (input.indexOf(',') > -1) {
|
||||
return input.split(',');
|
||||
}
|
||||
|
||||
return [input];
|
||||
}
|
||||
|
||||
class ParamParser {
|
||||
constructor(model, rawParams, locale) {
|
||||
this.parse = this.parse.bind(this);
|
||||
@@ -100,7 +110,12 @@ class ParamParser {
|
||||
// Checks to see
|
||||
async buildSearchParam(schema, key, val, operator) {
|
||||
let schemaObject = schema.obj[key];
|
||||
const localizedKey = this.getLocalizedKey(key, schemaObject);
|
||||
|
||||
let localizedKey = this.getLocalizedKey(key, schemaObject);
|
||||
|
||||
if (key === '_id' || key === 'id') {
|
||||
localizedKey = '_id';
|
||||
}
|
||||
|
||||
if (key.includes('.')) {
|
||||
const paths = key.split('.');
|
||||
@@ -171,11 +186,11 @@ class ParamParser {
|
||||
|
||||
case 'in':
|
||||
case 'all':
|
||||
formattedValue = { [`$${operator}`]: val.split(',') };
|
||||
formattedValue = { [`$${operator}`]: convertArrayFromCommaDelineated(val) };
|
||||
break;
|
||||
|
||||
case 'not_in':
|
||||
formattedValue = { $nin: val.split(',') };
|
||||
formattedValue = { $nin: convertArrayFromCommaDelineated(val) };
|
||||
break;
|
||||
|
||||
case 'not_equals':
|
||||
|
||||
Reference in New Issue
Block a user