2016-03-16 14:41:15 +01:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// Public dependencies
|
|
|
|
const _ = require('lodash');
|
|
|
|
const GraphQL = require('graphql');
|
2016-03-17 11:59:59 +01:00
|
|
|
const helpers = require('./helpers/');
|
|
|
|
const modelsUtils = require('../models/utils/');
|
2016-03-16 14:41:15 +01:00
|
|
|
const utils = require('./utils/');
|
|
|
|
|
|
|
|
// Core dependencies
|
|
|
|
const fs = require('fs-extra');
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Defaults parameters object
|
|
|
|
*/
|
|
|
|
|
|
|
|
defaults: {
|
|
|
|
collections: {},
|
|
|
|
usefulQueries: true
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Starter to manage conversion process and build valid GraphQL schemas
|
|
|
|
*/
|
|
|
|
|
|
|
|
getGraphQLSchema: function (params, cb) {
|
|
|
|
if (_.isEmpty(params.collections)) {
|
|
|
|
return 'Error: Empty object collections';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set defaults properties
|
|
|
|
this.defaults = _.assign(this.defaults, params);
|
|
|
|
|
|
|
|
const Query = this.getQueries();
|
|
|
|
const Mutation = _.get(this.defaults, 'ignoreMutations') === true ? null : this.getMutations();
|
|
|
|
|
|
|
|
const Schema = new GraphQL.GraphQLSchema(_.omit({
|
|
|
|
query: Query,
|
|
|
|
mutation: Mutation
|
|
|
|
}, _.isNull));
|
|
|
|
|
|
|
|
// Return schema
|
|
|
|
cb(Schema);
|
|
|
|
|
|
|
|
// Build policies
|
|
|
|
this.buildPolicies();
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build policies files
|
|
|
|
*/
|
|
|
|
|
|
|
|
buildPolicies: function () {
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
_.forEach(this.defaults.collections, function (collection, rootKey) {
|
|
|
|
// Identify queries related to this collection
|
|
|
|
const queries = _.pick(self.defaults.queryFields, function (query, key) {
|
|
|
|
if (key.indexOf(rootKey) !== -1 || key.indexOf(_.capitalize(rootKey)) !== -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Identify mutations related to this collection
|
|
|
|
const mutations = _.pick(self.defaults.mutations, function (query, key) {
|
|
|
|
if (key.indexOf(rootKey) !== -1 || key.indexOf(_.capitalize(rootKey)) !== -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Initialize query and mutations to empty array
|
|
|
|
const value = {
|
|
|
|
queries: _.mapValues(queries, function () {
|
|
|
|
return [];
|
|
|
|
}),
|
|
|
|
mutations: _.mapValues(mutations, function () {
|
|
|
|
return [];
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
fs.readJson(path.join(strapi.config.appPath, 'api', rootKey, 'config', 'graphql.json'), function (err, rootValue) {
|
|
|
|
// File doesn't exist
|
|
|
|
if (err && err.code === 'ENOENT' && err.syscall === 'open') {
|
|
|
|
rootValue = {};
|
|
|
|
} else if (err) {
|
|
|
|
console.log(err);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override or write file
|
|
|
|
fs.writeJson(path.join(strapi.config.appPath, 'api', rootKey, 'config', 'graphql.json'), _.merge(value, rootValue), function (err) {
|
|
|
|
if (err) {
|
|
|
|
console.log(err);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Manager to create queries for each collection
|
|
|
|
*/
|
|
|
|
|
|
|
|
getQueries: function () {
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
// Create required keys
|
|
|
|
this.defaults.types = {};
|
|
|
|
this.defaults.queryFields = {};
|
2016-03-17 11:59:59 +01:00
|
|
|
this.defaults.functions = {};
|
2016-03-16 14:41:15 +01:00
|
|
|
|
|
|
|
// Build Node Interface to expand compatibility
|
|
|
|
this.buildNodeInterface();
|
|
|
|
|
2016-03-17 11:59:59 +01:00
|
|
|
// Build functions object by ORM
|
|
|
|
_.forEach(this.defaults.collections, function (collection, key) {
|
|
|
|
self.buildFunctionsByORM(collection, key);
|
|
|
|
});
|
|
|
|
|
2016-03-16 14:41:15 +01:00
|
|
|
// Build GraphQL type system objects
|
|
|
|
_.forEach(this.defaults.collections, function (collection, key) {
|
|
|
|
self.buildType(collection, key);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Build GraphQL query
|
|
|
|
_.forEach(this.defaults.collections, function (collection, key) {
|
|
|
|
self.buildQueryFields(collection, key);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Build GraphQL query object
|
|
|
|
return new GraphQL.GraphQLObjectType({
|
|
|
|
name: 'Queries',
|
|
|
|
description: 'Root of the Schema',
|
|
|
|
fields: function () {
|
|
|
|
return self.defaults.queryFields;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Manager to create mutations for each collection
|
|
|
|
*/
|
|
|
|
getMutations: function () {
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
// Create require key
|
|
|
|
this.defaults.mutations = {};
|
|
|
|
|
|
|
|
// Build GraphQL mutation
|
|
|
|
_.forEach(this.defaults.collections, function (collection, key) {
|
|
|
|
self.buildMutation(collection, key);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Build GraphQL mutation object
|
|
|
|
return new GraphQL.GraphQLObjectType({
|
|
|
|
name: 'Mutations',
|
|
|
|
description: 'Mutations of the Schema',
|
|
|
|
fields: function () {
|
|
|
|
return self.defaults.mutations;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create GraphQL type system from BookShelf collection
|
|
|
|
*/
|
|
|
|
|
2016-03-17 11:59:59 +01:00
|
|
|
buildFunctionsByORM: function (collection, key) {
|
|
|
|
const ORM = modelsUtils.getORM(key);
|
|
|
|
|
|
|
|
if (!_.isUndefined(ORM) && _.isUndefined(_.get(this.defaults.functions, ORM))) {
|
|
|
|
_.set(this.defaults.functions, ORM, require('strapi-' + ORM + '/lib/utils/graphql'));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create GraphQL type system from BookShelf collection
|
|
|
|
*/
|
|
|
|
|
|
|
|
buildType: function (collection, key) {
|
2016-03-16 14:41:15 +01:00
|
|
|
const self = this;
|
2016-03-17 11:59:59 +01:00
|
|
|
const ORM = modelsUtils.getORM(key);
|
|
|
|
const collectionIdentity = this.defaults.functions[ORM].getCollectionIdentity(collection);
|
2016-03-16 14:41:15 +01:00
|
|
|
const collectionAttributes = collection._attributes;
|
|
|
|
|
|
|
|
const Type = new GraphQL.GraphQLObjectType({
|
|
|
|
name: _.capitalize(collectionIdentity),
|
|
|
|
description: 'This represents a/an ' + _.capitalize(collectionIdentity),
|
|
|
|
interfaces: [self.defaults.node],
|
|
|
|
fields: function () {
|
|
|
|
const fields = {};
|
|
|
|
|
|
|
|
_.forEach(collectionAttributes, function (rules, key) {
|
|
|
|
if (rules.hasOwnProperty('model')) {
|
|
|
|
fields[key] = {
|
|
|
|
type: self.defaults.types[_.capitalize(rules.model)],
|
|
|
|
resolve: function (object) {
|
|
|
|
const criteria = {};
|
|
|
|
criteria[collection.primaryKey] = object[key][self.defaults.collections[rules.model].primaryKey];
|
|
|
|
|
|
|
|
return self.defaults.queryFields[rules.model.toLowerCase()].resolve(object, criteria);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else if (rules.hasOwnProperty('collection')) {
|
|
|
|
fields[key] = {
|
|
|
|
type: new GraphQL.GraphQLList(self.defaults.types[_.capitalize(rules.collection)]),
|
|
|
|
resolve: function (object) {
|
|
|
|
const criteria = {};
|
|
|
|
criteria[rules.via.toLowerCase()] = object[collection.primaryKey];
|
|
|
|
|
|
|
|
return self.defaults.queryFields[rules.collection.toLowerCase() + 's'].resolve(object, {}, {
|
|
|
|
where: criteria
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
fields[key] = {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: rules.required ? new GraphQL.GraphQLNonNull(helpers.convertToGraphQLQueryType(rules)) : helpers.convertToGraphQLQueryType(rules)
|
2016-03-16 14:41:15 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Handle interface
|
|
|
|
fields.id = {
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString)
|
|
|
|
};
|
|
|
|
|
|
|
|
fields.type = {
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString)
|
|
|
|
};
|
|
|
|
|
|
|
|
return fields;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Save to global parameters
|
|
|
|
this.defaults.types[collectionIdentity] = Type;
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create query framework for each collection
|
|
|
|
*/
|
|
|
|
|
2016-03-17 11:59:59 +01:00
|
|
|
buildQueryFields: function (collection, key) {
|
|
|
|
const ORM = modelsUtils.getORM(key);
|
|
|
|
const collectionIdentity = this.defaults.functions[ORM].getCollectionIdentity(collection);
|
2016-03-16 14:41:15 +01:00
|
|
|
const fields = {};
|
|
|
|
|
|
|
|
// Get single record
|
|
|
|
fields[collectionIdentity.toLowerCase()] = {
|
|
|
|
type: this.defaults.types[collectionIdentity],
|
|
|
|
args: {
|
|
|
|
id: {
|
|
|
|
name: 'id',
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
resolve: function (rootValue, criteria) {
|
|
|
|
return utils.applyPolicies(rootValue, 'queries', collectionIdentity, collectionIdentity)
|
|
|
|
.then(function () {
|
2016-03-17 11:59:59 +01:00
|
|
|
return this.defaults.functions[ORM].fetch(collectionIdentity, collection, criteria);
|
2016-03-16 14:41:15 +01:00
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return _.isEmpty(data) ? data : data.toJSON();
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get multiples records
|
|
|
|
fields[collectionIdentity.toLowerCase() + 's'] = {
|
|
|
|
type: new GraphQL.GraphQLList(this.defaults.types[collectionIdentity]),
|
|
|
|
args: {
|
|
|
|
limit: {
|
|
|
|
name: 'limit',
|
|
|
|
type: GraphQL.GraphQLInt
|
|
|
|
},
|
|
|
|
skip: {
|
|
|
|
name: 'skip',
|
|
|
|
type: GraphQL.GraphQLInt
|
|
|
|
},
|
|
|
|
sort: {
|
|
|
|
name: 'sort',
|
|
|
|
type: GraphQL.GraphQLString
|
|
|
|
}
|
|
|
|
},
|
|
|
|
resolve: function (rootValue, criteria) {
|
|
|
|
return utils.applyPolicies(rootValue, 'queries', collectionIdentity, collectionIdentity + 's')
|
|
|
|
.then(function () {
|
2016-03-17 11:59:59 +01:00
|
|
|
return this.defaults.functions[ORM].fetchAll(collectionIdentity, collection, criteria);
|
2016-03-16 14:41:15 +01:00
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return data.toJSON() || data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (this.defaults.usefulQueries === true) {
|
|
|
|
// Get latest records sorted by creation date
|
|
|
|
fields['getLatest' + collectionIdentity + 's'] = {
|
|
|
|
type: new GraphQL.GraphQLList(this.defaults.types[collectionIdentity]),
|
|
|
|
args: {
|
|
|
|
count: {
|
|
|
|
name: 'count',
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLInt)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
resolve: function (rootValue, criteria) {
|
|
|
|
return utils.applyPolicies(rootValue, 'queries', collectionIdentity, 'getLatest' + collectionIdentity + 's')
|
|
|
|
.then(function () {
|
2016-03-17 11:59:59 +01:00
|
|
|
return this.defaults.functions[ORM].fetchLatest(collectionIdentity, collection, criteria);
|
2016-03-16 14:41:15 +01:00
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return data.toJSON() || data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get first records sorted by creation date
|
|
|
|
fields['getFirst' + collectionIdentity + 's'] = {
|
|
|
|
type: new GraphQL.GraphQLList(this.defaults.types[collectionIdentity]),
|
|
|
|
args: {
|
|
|
|
count: {
|
|
|
|
name: 'count',
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLInt)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
resolve: function (rootValue, criteria) {
|
|
|
|
return utils.applyPolicies(rootValue, 'queries', collectionIdentity, 'getFirst' + collectionIdentity + 's')
|
|
|
|
.then(function () {
|
2016-03-17 11:59:59 +01:00
|
|
|
return this.defaults.functions[ORM].fetchFirst(collectionIdentity, collection, criteria);
|
2016-03-16 14:41:15 +01:00
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return data.toJSON() || data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get count of records
|
|
|
|
fields['count' + collectionIdentity + 's'] = {
|
|
|
|
type: GraphQL.GraphQLInt,
|
|
|
|
resolve: function (rootValue) {
|
|
|
|
return utils.applyPolicies(rootValue, 'queries', collectionIdentity, 'count' + collectionIdentity + 's')
|
|
|
|
.then(function () {
|
2016-03-17 11:59:59 +01:00
|
|
|
return this.defaults.functions[ORM].count(collectionIdentity, collection);
|
2016-03-16 14:41:15 +01:00
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return data.toJSON() || data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply date filters to each query
|
|
|
|
_.forEach(_.omit(fields, collectionIdentity.toLowerCase()), function (field) {
|
|
|
|
if (_.isEmpty(field.args)) {
|
|
|
|
field.args = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
field.args.start = {
|
|
|
|
name: 'start',
|
|
|
|
type: GraphQL.GraphQLString
|
|
|
|
};
|
|
|
|
|
|
|
|
field.args.end = {
|
|
|
|
name: 'end',
|
|
|
|
type: GraphQL.GraphQLString
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
_.assign(this.defaults.queryFields, fields);
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create functions to do the same as an API
|
|
|
|
*/
|
|
|
|
|
|
|
|
buildMutation: function (collection) {
|
|
|
|
const self = this;
|
|
|
|
const collectionIdentity = _.capitalize(collection.forge().tableName);
|
|
|
|
const collectionAttributes = collection._attributes;
|
|
|
|
const PK = utils.getPK(collection);
|
|
|
|
const fields = {};
|
|
|
|
const args = {
|
|
|
|
required: {},
|
|
|
|
notRequired: {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Build args
|
|
|
|
_.forEach(collectionAttributes, function (rules, key) {
|
|
|
|
// Exclude relations
|
|
|
|
if (!rules.hasOwnProperty('model') && !rules.hasOwnProperty('collection') && rules.required) {
|
|
|
|
args.required[key] = {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: rules.required ? new GraphQL.GraphQLNonNull(helpers.convertToGraphQLQueryType(rules, self)) : helpers.convertToGraphQLQueryType(rules, self)
|
2016-03-16 14:41:15 +01:00
|
|
|
};
|
|
|
|
} else if (!rules.hasOwnProperty('model') && !rules.hasOwnProperty('collection') && !rules.required) {
|
|
|
|
args.notRequired[key] = {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: helpers.convertToGraphQLQueryType(rules, self)
|
2016-03-16 14:41:15 +01:00
|
|
|
};
|
|
|
|
} else if (rules.required) {
|
|
|
|
args.required[key] = {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: rules.required ? new GraphQL.GraphQLNonNull(helpers.convertToGraphQLRelationType(rules, self)) : helpers.convertToGraphQLRelationType(rules, self)
|
2016-03-16 14:41:15 +01:00
|
|
|
};
|
|
|
|
} else {
|
|
|
|
args.notRequired[key] = {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: rules.required ? new GraphQL.GraphQLNonNull(helpers.convertToGraphQLRelationType(rules, self)) : helpers.convertToGraphQLRelationType(rules, self)
|
2016-03-16 14:41:15 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Create record
|
|
|
|
fields['create' + collectionIdentity] = {
|
|
|
|
type: this.defaults.types[collectionIdentity],
|
|
|
|
resolve: function (rootValue, args) {
|
|
|
|
return utils.applyPolicies(rootValue, 'mutations', collectionIdentity, 'create' + collectionIdentity)
|
|
|
|
.then(function () {
|
|
|
|
_.merge(args, rootValue.context.request.body);
|
|
|
|
|
|
|
|
return strapi.services[collectionIdentity.toLowerCase()].add(rootValue.context.request.body);
|
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return _.isFunction(_.get(data, 'toJSON')) ? data.toJSON() : data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Set primary key as required for update/delete mutation
|
|
|
|
const argPK = _.set({}, PK, {
|
2016-03-17 11:59:59 +01:00
|
|
|
type: new GraphQL.GraphQLNonNull(helpers.convertToGraphQLQueryType(PK))
|
2016-03-16 14:41:15 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
// Update record(s)
|
|
|
|
fields['update' + collectionIdentity] = {
|
|
|
|
type: this.defaults.types[collectionIdentity],
|
|
|
|
args: _.assign(args.required, argPK),
|
|
|
|
resolve: function (rootValue, args) {
|
|
|
|
return utils.applyPolicies(rootValue, 'mutations', collectionIdentity, 'update' + collectionIdentity)
|
|
|
|
.then(function () {
|
|
|
|
_.merge(args, rootValue.context.request.body);
|
|
|
|
|
|
|
|
return strapi.services[collectionIdentity.toLowerCase()].edit(_.set({}, PK, args[PK]), _.omit(args, PK));
|
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return _.isFunction(_.get(data, 'toJSON')) ? data.toJSON() : data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Delete record(s)
|
|
|
|
fields['delete' + collectionIdentity] = {
|
|
|
|
type: this.defaults.types[collectionIdentity],
|
|
|
|
args: _.assign(args.notRequired, argPK),
|
|
|
|
resolve: function (rootValue, args) {
|
|
|
|
return utils.applyPolicies(rootValue, 'mutations', collectionIdentity, 'delete' + collectionIdentity)
|
|
|
|
.then(function () {
|
|
|
|
_.merge(args, rootValue.context.request.body);
|
|
|
|
|
|
|
|
return strapi.services[collectionIdentity.toLowerCase()].remove(args);
|
|
|
|
})
|
|
|
|
.then(function (data) {
|
|
|
|
return _.isFunction(_.get(data, 'toJSON')) ? data.toJSON() : data;
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
_.assign(this.defaults.mutations, fields);
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build node interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
buildNodeInterface: function () {
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
this.defaults.node = new GraphQL.GraphQLInterfaceType({
|
|
|
|
name: 'Node',
|
|
|
|
description: 'An object with an ID',
|
|
|
|
fields: function fields() {
|
|
|
|
return {
|
|
|
|
id: {
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString),
|
|
|
|
description: 'The global unique ID of an object'
|
|
|
|
},
|
|
|
|
type: {
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString),
|
|
|
|
description: 'The type of the object'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
|
|
|
resolveType: function resolveType(object) {
|
|
|
|
return object.type;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.defaults.nodeFields = {
|
|
|
|
name: 'Node',
|
|
|
|
type: this.defaults.node,
|
|
|
|
description: 'A node interface field',
|
|
|
|
args: {
|
|
|
|
id: {
|
|
|
|
type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString),
|
|
|
|
description: 'Id of node interface'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
resolve: function resolve(object, criteria) {
|
|
|
|
const arrayOfPromises = [];
|
|
|
|
|
|
|
|
// Search value in each collection
|
|
|
|
_.forEach(self.defaults.collections, function (collection) {
|
|
|
|
arrayOfPromises.push(collection.find(criteria));
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all(arrayOfPromises)
|
|
|
|
.then(function (results) {
|
|
|
|
let typeIndex;
|
|
|
|
let object;
|
|
|
|
|
|
|
|
_.forEach(results, function (value, index) {
|
|
|
|
if (_.size(value) === 1) {
|
|
|
|
// Save the index
|
|
|
|
typeIndex = index;
|
|
|
|
|
|
|
|
// Get object from array
|
|
|
|
object = _.first(value);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
object.type = self.defaults.queryFields[_.keys(self.defaults.queryFields)[typeIndex]].type;
|
|
|
|
|
|
|
|
return object;
|
|
|
|
})
|
|
|
|
.catch(function (error) {
|
|
|
|
return error;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|