recycles findByID mongoose query within GraphQL relationship queries
This commit is contained in:
@@ -1,18 +1,35 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
const withPolicy = require('../../../graphql/resolvers/withPolicy');
|
||||
const findQuery = require('../../queries/find');
|
||||
|
||||
const find = ({ config, model }) => {
|
||||
return withPolicy(
|
||||
config.policies.read,
|
||||
async (_, args) => {
|
||||
async (_, args, context) => {
|
||||
const options = {
|
||||
depth: 0,
|
||||
model,
|
||||
query: args,
|
||||
locale: args.locale,
|
||||
query: Object.keys(args).reduce((query, arg) => {
|
||||
if (arg === 'where') {
|
||||
return {
|
||||
...query,
|
||||
arg: args[arg],
|
||||
};
|
||||
}
|
||||
|
||||
return query;
|
||||
}),
|
||||
};
|
||||
|
||||
if (args.fallbackLocale) options.fallbackLocale = args.fallbackLocale;
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const results = await findQuery(options);
|
||||
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
const withPolicy = require('../../../graphql/resolvers/withPolicy');
|
||||
const findByIDQuery = require('../../queries/findByID');
|
||||
|
||||
const findByID = ({ config, model }) => withPolicy(
|
||||
config.policies.read,
|
||||
async (parent, { id }, context) => {
|
||||
async (_, args, context) => {
|
||||
const options = {
|
||||
depth: 0,
|
||||
model,
|
||||
id,
|
||||
locale: context.locale,
|
||||
id: args.id,
|
||||
};
|
||||
|
||||
if (context.query['fallback-locale']) options.fallbackLocale = context.query['fallback-locale'];
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await findByIDQuery(options);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ const find = async (options) => {
|
||||
}),
|
||||
};
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw new APIError();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,10 @@ const mongoose = require('mongoose');
|
||||
const { NotFound } = require('../../errors');
|
||||
|
||||
const findByID = async (options) => {
|
||||
const mongooseOptions = {};
|
||||
const mongooseOptions = {
|
||||
options: {},
|
||||
};
|
||||
|
||||
const {
|
||||
depth, locale, fallbackLocale, model, id,
|
||||
} = options;
|
||||
@@ -17,11 +20,11 @@ const findByID = async (options) => {
|
||||
mongooseOptions.options.autopopulate = false;
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
try {
|
||||
// Await pre find hook here
|
||||
|
||||
let result;
|
||||
|
||||
if (hasMultipleIDs) {
|
||||
result = await model.find({
|
||||
_id: {
|
||||
@@ -32,14 +35,18 @@ const findByID = async (options) => {
|
||||
result = await model.findOne({ _id: id }, {}, mongooseOptions);
|
||||
}
|
||||
|
||||
if (result.length === 0) throw new NotFound();
|
||||
if (!result || (result && result.length === 0)) throw new NotFound();
|
||||
|
||||
if (hasMultipleIDs) {
|
||||
result = result.map((doc) => {
|
||||
return result.map((doc) => {
|
||||
if (locale && doc.setLocale) doc.setLocale(locale, fallbackLocale);
|
||||
return doc.toJSON({ virtuals: true });
|
||||
});
|
||||
} else if (locale && result.setLocale) result = result.setLocale(locale, fallbackLocale);
|
||||
}
|
||||
|
||||
if (locale && result.setLocale) {
|
||||
result.setLocale(locale, fallbackLocale);
|
||||
}
|
||||
|
||||
// Await post find hook here
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
/* eslint-disable no-use-before-define */
|
||||
const {
|
||||
GraphQLString,
|
||||
@@ -12,9 +14,10 @@ const {
|
||||
const formatName = require('../utilities/formatName');
|
||||
const combineParentName = require('../utilities/combineParentName');
|
||||
const withNullableType = require('./withNullableType');
|
||||
const findByID = require('../../collections/queries/findByID');
|
||||
|
||||
function getBuildObjectType(context) {
|
||||
const buildObjectType = (name, fields, parent, resolver) => {
|
||||
function getBuildObjectType(graphQLContext) {
|
||||
const buildObjectType = (name, fields, parentName) => {
|
||||
const fieldToSchemaMap = {
|
||||
number: field => ({ type: withNullableType(field, GraphQLFloat) }),
|
||||
text: field => ({ type: withNullableType(field, GraphQLString) }),
|
||||
@@ -26,7 +29,7 @@ function getBuildObjectType(context) {
|
||||
upload: field => ({ type: withNullableType(field, GraphQLString) }),
|
||||
checkbox: field => ({ type: withNullableType(field, GraphQLBoolean) }),
|
||||
select: (field) => {
|
||||
const fullName = combineParentName(parent, field.name);
|
||||
const fullName = combineParentName(parentName, field.name);
|
||||
|
||||
let type = new GraphQLEnumType({
|
||||
name: fullName,
|
||||
@@ -60,22 +63,25 @@ function getBuildObjectType(context) {
|
||||
},
|
||||
relationship: (field) => {
|
||||
const { relationTo, label } = field;
|
||||
const isRelatedToManyCollections = Array.isArray(relationTo);
|
||||
const hasManyValues = field.hasMany;
|
||||
|
||||
let type;
|
||||
|
||||
if (Array.isArray(relationTo)) {
|
||||
if (isRelatedToManyCollections) {
|
||||
const types = relationTo.map((relation) => {
|
||||
return context.collections[relation].graphQLType;
|
||||
return graphQLContext.collections[relation].graphQLType;
|
||||
});
|
||||
|
||||
type = new GraphQLUnionType({
|
||||
name: combineParentName(parent, label),
|
||||
name: combineParentName(parentName, label),
|
||||
types,
|
||||
resolveType(data) {
|
||||
return context.types.blockTypes[data.blockType];
|
||||
return graphQLContext.types.blockTypes[data.blockType];
|
||||
},
|
||||
});
|
||||
} else {
|
||||
type = context.collections[relationTo].graphQLType;
|
||||
type = graphQLContext.collections[relationTo].graphQLType;
|
||||
}
|
||||
|
||||
// If the relationshipType is undefined at this point,
|
||||
@@ -86,33 +92,81 @@ function getBuildObjectType(context) {
|
||||
type = type || newlyCreatedBlockType;
|
||||
|
||||
return {
|
||||
type: field.hasMany ? new GraphQLList(type) : type,
|
||||
type: hasManyValues ? new GraphQLList(type) : type,
|
||||
async resolve(parent, args, context) {
|
||||
const value = parent[field.name];
|
||||
const locale = args.locale || context.locale;
|
||||
const fallbackLocale = args.fallbackLocale || context.fallbackLocale;
|
||||
let relatedCollectionSlug = field.relationTo;
|
||||
|
||||
if (hasManyValues) {
|
||||
const results = [];
|
||||
|
||||
if (value) {
|
||||
for (const relatedDoc of value) {
|
||||
let id = relatedDoc;
|
||||
|
||||
if (isRelatedToManyCollections) {
|
||||
relatedCollectionSlug = relatedDoc.relationTo;
|
||||
id = relatedDoc.value;
|
||||
}
|
||||
|
||||
const result = await findByID({
|
||||
model: graphQLContext.collections[relatedCollectionSlug].model,
|
||||
id,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
});
|
||||
|
||||
results.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
let id = value;
|
||||
if (isRelatedToManyCollections && value) id = value.value;
|
||||
|
||||
if (id) {
|
||||
id = id.toString();
|
||||
|
||||
const relatedDocument = await findByID({
|
||||
model: graphQLContext.collections[relatedCollectionSlug].model,
|
||||
id,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
});
|
||||
|
||||
return relatedDocument;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
repeater: (field) => {
|
||||
const fullName = combineParentName(parent, field.label);
|
||||
const fullName = combineParentName(parentName, field.label);
|
||||
let type = buildObjectType(fullName, field.fields, fullName);
|
||||
type = new GraphQLList(withNullableType(field, type));
|
||||
|
||||
return { type };
|
||||
},
|
||||
group: (field) => {
|
||||
const fullName = combineParentName(parent, field.label);
|
||||
const fullName = combineParentName(parentName, field.label);
|
||||
const type = buildObjectType(fullName, field.fields, fullName);
|
||||
|
||||
return { type };
|
||||
},
|
||||
flexible: (field) => {
|
||||
const blockTypes = field.blocks.map((block) => {
|
||||
context.buildBlockTypeIfMissing(block);
|
||||
return context.types.blockTypes[block.slug];
|
||||
graphQLContext.buildBlockTypeIfMissing(block);
|
||||
return graphQLContext.types.blockTypes[block.slug];
|
||||
});
|
||||
|
||||
const type = new GraphQLList(new GraphQLUnionType({
|
||||
name: combineParentName(parent, field.label),
|
||||
name: combineParentName(parentName, field.label),
|
||||
types: blockTypes,
|
||||
resolveType(data) {
|
||||
return context.types.blockTypes[data.blockType];
|
||||
return graphQLContext.types.blockTypes[data.blockType];
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -135,10 +189,6 @@ function getBuildObjectType(context) {
|
||||
}, {}),
|
||||
};
|
||||
|
||||
if (resolver) {
|
||||
objectSchema.resolve = resolver;
|
||||
}
|
||||
|
||||
const newlyCreatedBlockType = new GraphQLObjectType(objectSchema);
|
||||
|
||||
return newlyCreatedBlockType;
|
||||
|
||||
Reference in New Issue
Block a user