Allow SDL type definitions to beneficiate from Nexus types context & processing

This commit is contained in:
Convly 2022-02-04 17:31:53 +01:00
parent af0cba8c5b
commit fe4645c385
3 changed files with 32 additions and 38 deletions

View File

@ -43,7 +43,7 @@
"graphql-upload": "^13.0.0", "graphql-upload": "^13.0.0",
"koa-compose": "^4.1.0", "koa-compose": "^4.1.0",
"lodash": "4.17.21", "lodash": "4.17.21",
"nexus": "1.1.0", "nexus": "1.2.0",
"pluralize": "^8.0.0", "pluralize": "^8.0.0",
"subscriptions-transport-ws": "0.9.19" "subscriptions-transport-ws": "0.9.19"
}, },

View File

@ -1,10 +1,6 @@
'use strict'; 'use strict';
const { const { mergeSchemas, addResolversToSchema } = require('@graphql-tools/schema');
mergeSchemas,
makeExecutableSchema,
addResolversToSchema,
} = require('@graphql-tools/schema');
const { pruneSchema } = require('@graphql-tools/utils'); const { pruneSchema } = require('@graphql-tools/utils');
const { makeSchema } = require('nexus'); const { makeSchema } = require('nexus');
const { prop, startsWith } = require('lodash/fp'); const { prop, startsWith } = require('lodash/fp');
@ -54,11 +50,8 @@ module.exports = ({ strapi }) => {
shadowCRUD(); shadowCRUD();
} }
// Build a collection of schema based on the type registry (& temporary generated extension) // Build a merged schema from both Nexus types & SDL type definitions
const schemas = buildSchemas({ registry }); const schema = buildMergedSchema({ registry });
// Merge every created schema into a single one
const mergedSchema = mergeSchemas({ schemas });
// Generate the extension configuration for the content API. // Generate the extension configuration for the content API.
// This extension instance needs to be generated after the Nexus schema's // This extension instance needs to be generated after the Nexus schema's
@ -67,42 +60,43 @@ module.exports = ({ strapi }) => {
const extension = extensionService.generate({ typeRegistry: registry }); const extension = extensionService.generate({ typeRegistry: registry });
// Add the extension's resolvers to the final schema // Add the extension's resolvers to the final schema
const schema = addResolversToSchema(mergedSchema, extension.resolvers); const schemaWithResolvers = addResolversToSchema(schema, extension.resolvers);
const nexusSchema = makeSchema({
// Build the schema from the merged GraphQL schema.
// Since we're passing the schema to the mergeSchema property, it'll transform our SDL type definitions
// into Nexus type definition, thus allowing them to be handled bu Nexus plugins & other processing
mergeSchema: { schema: schemaWithResolvers },
// Apply user-defined plugins
plugins: extension.plugins,
});
// Wrap resolvers if needed (auth, middlewares, policies...) as configured in the extension // Wrap resolvers if needed (auth, middlewares, policies...) as configured in the extension
const wrappedSchema = wrapResolvers({ schema, strapi, extension }); const wrappedNexusSchema = wrapResolvers({ schema: nexusSchema, strapi, extension });
// Prune schema, remove unused types // Prune schema, remove unused types
// eg: removes registered subscriptions if they're disabled in the config) // eg: removes registered subscriptions if they're disabled in the config)
const prunedSchema = pruneSchema(wrappedSchema); const prunedNexusSchema = pruneSchema(wrappedNexusSchema);
return prunedSchema; return prunedNexusSchema;
}; };
const buildSchemas = ({ registry }) => { const buildMergedSchema = ({ registry }) => {
// Here we extract types, plugins & typeDefs from a temporary generated // Here we extract types, plugins & typeDefs from a temporary generated
// extension since there won't be any addition allowed after schemas generation // extension since there won't be any addition allowed after schemas generation
const { types, plugins, typeDefs = [] } = extensionService.generate({ typeRegistry: registry }); const { types, typeDefs = [] } = extensionService.generate({ typeRegistry: registry });
// Create a new Nexus schema (shadow CRUD) & add it to the schemas collection // Nexus schema built with user-defined & shadow CRUD auto generated Nexus types
const nexusSchema = makeSchema({ const nexusSchema = makeSchema({ types: [registry.definitions, types] });
types: [
// Add the auto-generated Nexus types (shadow CRUD)
registry.definitions,
// Add every Nexus type registered using the extension service
types,
],
plugins: [ // Merge type definitions with the Nexus schema
// Add every plugin registered using the extension service return mergeSchemas({
...plugins, typeDefs,
], // Give access to the shadowCRUD & nexus based types
// Note: This is necessary so that types defined in SDL can reference types defined with Nexus
schemas: [nexusSchema],
}); });
// Build schemas based on SDL type definitions (defined in the extension)
const sdlSchemas = typeDefs.map(sdl => makeExecutableSchema({ typeDefs: sdl }));
return [nexusSchema, ...sdlSchemas];
}; };
const shadowCRUD = () => { const shadowCRUD = () => {

View File

@ -16124,10 +16124,10 @@ netmask@^2.0.1:
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
nexus@1.1.0: nexus@1.2.0:
version "1.1.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/nexus/-/nexus-1.1.0.tgz#3d8fa05c29e7a61aa55f64ef5e0ba43dd76b3ed6" resolved "https://registry.yarnpkg.com/nexus/-/nexus-1.2.0.tgz#12c4611702184fac170c98c1a2c778a76a9e9827"
integrity sha512-jUhbg22gKVY2YwZm726BrbfHaQ7Xzc0hNXklygDhuqaVxCuHCgFMhWa2svNWd1npe8kfeiu5nbwnz+UnhNXzCQ== integrity sha512-7+0240LrQNnKKLTgbxM6KLLdfMgm4wp1TPAULim0lGmHfX7QsJK39i2KmFdMr3WdsAKoybMmwyrJtaYOq0q62g==
dependencies: dependencies:
iterall "^1.3.0" iterall "^1.3.0"
tslib "^2.0.3" tslib "^2.0.3"