mirror of
https://github.com/strapi/strapi.git
synced 2025-11-11 15:49:50 +00:00
Split graphql schema generator code
Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
parent
44b7ab6858
commit
c02625e438
@ -13,7 +13,7 @@ const Query = require('./Query.js');
|
|||||||
const Mutation = require('./Mutation.js');
|
const Mutation = require('./Mutation.js');
|
||||||
const Types = require('./Types.js');
|
const Types = require('./Types.js');
|
||||||
const Resolvers = require('./Resolvers.js');
|
const Resolvers = require('./Resolvers.js');
|
||||||
const { mergeSchemas } = require('./utils');
|
const { mergeSchemas, createDefaultSchema } = require('./utils');
|
||||||
|
|
||||||
const schemaBuilder = {
|
const schemaBuilder = {
|
||||||
/**
|
/**
|
||||||
@ -128,39 +128,13 @@ const schemaBuilder = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
generateSchema: function() {
|
generateSchema: function() {
|
||||||
|
const shadowCRUDEnabled =
|
||||||
|
strapi.plugins.graphql.config.shadowCRUD !== false;
|
||||||
|
|
||||||
// Generate type definition and query/mutation for models.
|
// Generate type definition and query/mutation for models.
|
||||||
let shadowCRUD = { definition: '', query: '', mutation: '', resolvers: {} };
|
const shadowCRUD = shadowCRUDEnabled
|
||||||
|
? this.buildShadowCRUD()
|
||||||
// build defaults schemas if shadowCRUD is enabled
|
: createDefaultSchema();
|
||||||
if (strapi.plugins.graphql.config.shadowCRUD !== false) {
|
|
||||||
const modelCruds = Resolvers.buildShadowCRUD(
|
|
||||||
_.omitBy(strapi.models, model => model.internal === true)
|
|
||||||
);
|
|
||||||
|
|
||||||
shadowCRUD = Object.keys(strapi.plugins).reduce((acc, plugin) => {
|
|
||||||
const {
|
|
||||||
definition,
|
|
||||||
query,
|
|
||||||
mutation,
|
|
||||||
resolvers,
|
|
||||||
} = Resolvers.buildShadowCRUD(strapi.plugins[plugin].models);
|
|
||||||
|
|
||||||
// We cannot put this in the merge because it's a string.
|
|
||||||
acc.definition += definition || '';
|
|
||||||
|
|
||||||
return _.merge(acc, {
|
|
||||||
query,
|
|
||||||
resolvers,
|
|
||||||
mutation,
|
|
||||||
});
|
|
||||||
}, modelCruds);
|
|
||||||
}
|
|
||||||
|
|
||||||
const componentSchemas = Object.values(strapi.components).map(compo =>
|
|
||||||
Resolvers.buildComponent(compo)
|
|
||||||
);
|
|
||||||
|
|
||||||
mergeSchemas(shadowCRUD, ...componentSchemas);
|
|
||||||
|
|
||||||
// Extract custom definition, query or resolver.
|
// Extract custom definition, query or resolver.
|
||||||
const {
|
const {
|
||||||
@ -171,114 +145,57 @@ const schemaBuilder = {
|
|||||||
} = strapi.plugins.graphql.config._schema.graphql;
|
} = strapi.plugins.graphql.config._schema.graphql;
|
||||||
|
|
||||||
// Polymorphic.
|
// Polymorphic.
|
||||||
const {
|
const polymorphicSchema = Types.addPolymorphicUnionType(
|
||||||
polymorphicDef,
|
definition + shadowCRUD.definition
|
||||||
polymorphicResolver,
|
);
|
||||||
} = Types.addPolymorphicUnionType(definition, shadowCRUD.definition);
|
|
||||||
|
|
||||||
// Build resolvers.
|
// Build resolvers.
|
||||||
const resolvers =
|
const resolvers =
|
||||||
_.omitBy(
|
_.omitBy(
|
||||||
_.merge(shadowCRUD.resolvers, resolver, polymorphicResolver),
|
_.merge(shadowCRUD.resolvers, resolver, polymorphicSchema.resolvers),
|
||||||
_.isEmpty
|
_.isEmpty
|
||||||
) || {};
|
) || {};
|
||||||
|
|
||||||
// Transform object to only contain function.
|
this.buildResolvers(resolvers);
|
||||||
Object.keys(resolvers).reduce((acc, type) => {
|
|
||||||
if (graphql.isScalarType(acc[type])) {
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.keys(acc[type]).reduce((acc, resolverName) => {
|
|
||||||
const resolverObj = acc[type][resolverName];
|
|
||||||
// Disabled this query.
|
|
||||||
if (resolverObj === false) {
|
|
||||||
delete acc[type][resolverName];
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_.isFunction(resolverObj)) {
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
let plugin;
|
|
||||||
if (_.has(resolverObj, ['plugin'])) {
|
|
||||||
plugin = resolverObj.plugin;
|
|
||||||
} else if (_.has(resolverObj, ['resolver', 'plugin'])) {
|
|
||||||
plugin = resolverObj.resolver.plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'Mutation': {
|
|
||||||
let name, action;
|
|
||||||
if (
|
|
||||||
_.has(resolverObj, ['resolver']) &&
|
|
||||||
_.isString(resolverObj.resolver)
|
|
||||||
) {
|
|
||||||
[name, action] = resolverObj.resolver.split('.');
|
|
||||||
} else if (
|
|
||||||
_.has(resolverObj, ['resolver', 'handler']) &&
|
|
||||||
_.isString(resolverObj.resolver.handler)
|
|
||||||
) {
|
|
||||||
[name, action] = resolverObj.resolver.handler.split('.');
|
|
||||||
} else {
|
|
||||||
name = null;
|
|
||||||
action = resolverName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutationResolver = Mutation.composeMutationResolver({
|
|
||||||
_schema: strapi.plugins.graphql.config._schema.graphql,
|
|
||||||
plugin,
|
|
||||||
name: _.toLower(name),
|
|
||||||
action,
|
|
||||||
});
|
|
||||||
|
|
||||||
acc[type][resolverName] = mutationResolver;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'Query':
|
|
||||||
default: {
|
|
||||||
acc[type][resolverName] = Query.composeQueryResolver({
|
|
||||||
_schema: strapi.plugins.graphql.config._schema.graphql,
|
|
||||||
plugin,
|
|
||||||
name: resolverName,
|
|
||||||
isSingular: 'force', // Avoid singular/pluralize and force query name.
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, acc);
|
|
||||||
}, resolvers);
|
|
||||||
|
|
||||||
// Return empty schema when there is no model.
|
// Return empty schema when there is no model.
|
||||||
if (_.isEmpty(shadowCRUD.definition) && _.isEmpty(definition)) {
|
if (_.isEmpty(shadowCRUD.definition) && _.isEmpty(definition)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const queryFields = this.formatGQL(
|
||||||
|
shadowCRUD.query,
|
||||||
|
resolver.Query,
|
||||||
|
null,
|
||||||
|
'query'
|
||||||
|
);
|
||||||
|
|
||||||
|
const mutationFields = this.formatGQL(
|
||||||
|
shadowCRUD.mutation,
|
||||||
|
resolver.Mutation,
|
||||||
|
null,
|
||||||
|
'mutation'
|
||||||
|
);
|
||||||
|
|
||||||
// Concatenate.
|
// Concatenate.
|
||||||
let typeDefs = `
|
let typeDefs = `
|
||||||
${definition}
|
${definition}
|
||||||
${shadowCRUD.definition}
|
${shadowCRUD.definition}
|
||||||
type Query {${shadowCRUD.query &&
|
${polymorphicSchema.definition}
|
||||||
this.formatGQL(
|
|
||||||
shadowCRUD.query,
|
|
||||||
resolver.Query,
|
|
||||||
null,
|
|
||||||
'query'
|
|
||||||
)}${query}}
|
|
||||||
type Mutation {${shadowCRUD.mutation &&
|
|
||||||
this.formatGQL(
|
|
||||||
shadowCRUD.mutation,
|
|
||||||
resolver.Mutation,
|
|
||||||
null,
|
|
||||||
'mutation'
|
|
||||||
)}${mutation}}
|
|
||||||
${Types.addCustomScalar(resolvers)}
|
|
||||||
${Types.addInput()}
|
${Types.addInput()}
|
||||||
${polymorphicDef}
|
|
||||||
|
type Query {
|
||||||
|
${queryFields}
|
||||||
|
${query}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
${mutationFields}
|
||||||
|
${mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
${Types.addCustomScalar(resolvers)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// // Build schema.
|
// // Build schema.
|
||||||
@ -310,6 +227,92 @@ const schemaBuilder = {
|
|||||||
writeGenerateSchema: schema => {
|
writeGenerateSchema: schema => {
|
||||||
return strapi.fs.writeAppFile('exports/graphql/schema.graphql', schema);
|
return strapi.fs.writeAppFile('exports/graphql/schema.graphql', schema);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
buildShadowCRUD() {
|
||||||
|
const modelSchema = Resolvers.buildShadowCRUD(
|
||||||
|
_.omitBy(strapi.models, model => model.internal === true)
|
||||||
|
);
|
||||||
|
|
||||||
|
const pluginSchemas = Object.keys(strapi.plugins).reduce((acc, plugin) => {
|
||||||
|
const schemas = Resolvers.buildShadowCRUD(strapi.plugins[plugin].models);
|
||||||
|
return acc.concat(schemas);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const componentSchemas = Object.values(strapi.components).map(compo =>
|
||||||
|
Resolvers.buildComponent(compo)
|
||||||
|
);
|
||||||
|
|
||||||
|
const schema = { definition: '', resolvers: {}, query: {}, mutation: {} };
|
||||||
|
mergeSchemas(schema, modelSchema, ...pluginSchemas, ...componentSchemas);
|
||||||
|
|
||||||
|
return schema;
|
||||||
|
},
|
||||||
|
|
||||||
|
buildResolvers(resolvers) {
|
||||||
|
// Transform object to only contain function.
|
||||||
|
Object.keys(resolvers).reduce((acc, type) => {
|
||||||
|
if (graphql.isScalarType(acc[type])) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(acc[type]).reduce((acc, resolverName) => {
|
||||||
|
const resolverObj = acc[type][resolverName];
|
||||||
|
// Disabled this query.
|
||||||
|
if (resolverObj === false) {
|
||||||
|
delete acc[type][resolverName];
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isFunction(resolverObj)) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugin =
|
||||||
|
_.get(resolverObj, ['plugin']) ||
|
||||||
|
_.get(resolverObj, ['resolver', 'plugin']);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'Mutation': {
|
||||||
|
const resolver =
|
||||||
|
_.get(resolverObj, ['resolver', 'handler']) ||
|
||||||
|
_.get(resolverObj, ['resolver']);
|
||||||
|
|
||||||
|
let name, action;
|
||||||
|
|
||||||
|
if (_.isString(resolver)) {
|
||||||
|
[name, action] = resolver.split('.');
|
||||||
|
} else {
|
||||||
|
name = null;
|
||||||
|
action = resolverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutationResolver = Mutation.composeMutationResolver({
|
||||||
|
_schema: strapi.plugins.graphql.config._schema.graphql,
|
||||||
|
plugin,
|
||||||
|
name: _.toLower(name),
|
||||||
|
action,
|
||||||
|
});
|
||||||
|
|
||||||
|
acc[type][resolverName] = mutationResolver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'Query':
|
||||||
|
default: {
|
||||||
|
acc[type][resolverName] = Query.composeQueryResolver({
|
||||||
|
_schema: strapi.plugins.graphql.config._schema.graphql,
|
||||||
|
plugin,
|
||||||
|
name: resolverName,
|
||||||
|
isSingular: 'force', // Avoid singular/pluralize and force query name.
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, acc);
|
||||||
|
}, resolvers);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = schemaBuilder;
|
module.exports = schemaBuilder;
|
||||||
|
|||||||
@ -205,11 +205,9 @@ module.exports = {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
addPolymorphicUnionType(customDefs, defs) {
|
addPolymorphicUnionType(definition) {
|
||||||
const def = customDefs + defs;
|
|
||||||
|
|
||||||
const types = graphql
|
const types = graphql
|
||||||
.parse(def)
|
.parse(definition)
|
||||||
.definitions.filter(
|
.definitions.filter(
|
||||||
def => def.kind === 'ObjectTypeDefinition' && def.name.value !== 'Query'
|
def => def.kind === 'ObjectTypeDefinition' && def.name.value !== 'Query'
|
||||||
)
|
)
|
||||||
@ -217,8 +215,8 @@ module.exports = {
|
|||||||
|
|
||||||
if (types.length > 0) {
|
if (types.length > 0) {
|
||||||
return {
|
return {
|
||||||
polymorphicDef: `union Morph = ${types.join(' | ')}`,
|
definition: `union Morph = ${types.join(' | ')}`,
|
||||||
polymorphicResolver: {
|
resolvers: {
|
||||||
Morph: {
|
Morph: {
|
||||||
__resolveType(obj) {
|
__resolveType(obj) {
|
||||||
return obj.kind || obj.__contentType || null;
|
return obj.kind || obj.__contentType || null;
|
||||||
@ -229,8 +227,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
polymorphicDef: '',
|
definition: '',
|
||||||
polymorphicResolver: {},
|
resolvers: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,14 @@ const mergeSchemas = (root, ...subs) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createDefaultSchema = () => ({
|
||||||
|
definition: '',
|
||||||
|
query: '',
|
||||||
|
mutation: '',
|
||||||
|
resolvers: {},
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mergeSchemas,
|
mergeSchemas,
|
||||||
|
createDefaultSchema,
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user