| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  | const { isEmpty, mergeWith, isArray } = require('lodash/fp'); | 
					
						
							| 
									
										
										
										
											2021-09-29 13:10:33 +02:00
										 |  |  | const { execute, subscribe } = require('graphql'); | 
					
						
							|  |  |  | const { SubscriptionServer } = require('subscriptions-transport-ws'); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | const { ApolloServer } = require('apollo-server-koa'); | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | const { | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |   ApolloServerPluginLandingPageDisabled, | 
					
						
							|  |  |  |   ApolloServerPluginLandingPageGraphQLPlayground, | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | } = require('apollo-server-core'); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | const depthLimit = require('graphql-depth-limit'); | 
					
						
							|  |  |  | const { graphqlUploadKoa } = require('graphql-upload'); | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  | const formatGraphqlError = require('./format-graphql-error'); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  | const merge = mergeWith((a, b) => { | 
					
						
							|  |  |  |   if (isArray(a) && isArray(b)) { | 
					
						
							|  |  |  |     return a.concat(b); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-28 16:54:07 +02:00
										 |  |  | module.exports = async ({ strapi }) => { | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |   // Generate the GraphQL schema for the content API
 | 
					
						
							| 
									
										
										
										
											2021-08-23 19:04:19 +02:00
										 |  |  |   const schema = strapi | 
					
						
							|  |  |  |     .plugin('graphql') | 
					
						
							| 
									
										
										
										
											2021-09-01 12:06:51 +02:00
										 |  |  |     .service('content-api') | 
					
						
							|  |  |  |     .buildSchema(); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |   if (isEmpty(schema)) { | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |     strapi.log.warn('The GraphQL schema has not been generated because it is empty'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 16:04:32 +01:00
										 |  |  |   const { config } = strapi.plugin('graphql'); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 16:04:32 +01:00
										 |  |  |   const path = config('endpoint'); | 
					
						
							| 
									
										
										
										
											2021-09-29 13:10:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |   const defaultServerConfig = { | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |     // Schema
 | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |     schema, | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Initialize loaders for this request.
 | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |     context: ({ ctx }) => ({ | 
					
						
							|  |  |  |       state: ctx.state, | 
					
						
							|  |  |  |       koaContext: ctx, | 
					
						
							|  |  |  |     }), | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |     // Validation
 | 
					
						
							| 
									
										
										
										
											2021-11-10 16:04:32 +01:00
										 |  |  |     validationRules: [depthLimit(config('depthLimit'))], | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     // Errors
 | 
					
						
							|  |  |  |     formatError: formatGraphqlError, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |     // Misc
 | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |     cors: false, | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |     uploads: false, | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |     bodyParserConfig: true, | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     plugins: [ | 
					
						
							| 
									
										
										
										
											2021-12-22 17:15:46 +01:00
										 |  |  |       process.env.NODE_ENV === 'production' && !config('playgroundAlways') | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |         ? ApolloServerPluginLandingPageDisabled() | 
					
						
							|  |  |  |         : ApolloServerPluginLandingPageGraphQLPlayground(), | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |     ], | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 16:04:32 +01:00
										 |  |  |   const serverConfig = merge(defaultServerConfig, config('apolloServer')); | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 13:10:33 +02:00
										 |  |  |   // Handle subscriptions
 | 
					
						
							| 
									
										
										
										
											2021-11-10 16:04:32 +01:00
										 |  |  |   if (config('subscriptions')) { | 
					
						
							| 
									
										
										
										
											2021-09-29 13:10:33 +02:00
										 |  |  |     const subscriptionServer = SubscriptionServer.create( | 
					
						
							|  |  |  |       { schema, execute, subscribe }, | 
					
						
							|  |  |  |       { server: strapi.server.httpServer, path } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     serverConfig.plugins.push({ | 
					
						
							|  |  |  |       async serverWillStart() { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           async drainServer() { | 
					
						
							|  |  |  |             subscriptionServer.close(); | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |   // Create a new Apollo server
 | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |   const server = new ApolloServer(serverConfig); | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Register the upload middleware
 | 
					
						
							| 
									
										
										
										
											2021-09-28 11:11:03 +02:00
										 |  |  |   useUploadMiddleware(strapi, path); | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     // Since Apollo-Server v3, server.start() must be called before using server.applyMiddleware()
 | 
					
						
							|  |  |  |     await server.start(); | 
					
						
							|  |  |  |   } catch (e) { | 
					
						
							|  |  |  |     strapi.log.error('Failed to start the Apollo server', e.message); | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 13:10:33 +02:00
										 |  |  |   // Link the Apollo server & the Strapi app
 | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |   strapi.server.routes([ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       method: 'ALL', | 
					
						
							| 
									
										
										
										
											2021-09-21 19:38:15 +02:00
										 |  |  |       path, | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |       handler: [ | 
					
						
							|  |  |  |         (ctx, next) => { | 
					
						
							|  |  |  |           ctx.state.route = { | 
					
						
							|  |  |  |             info: { | 
					
						
							|  |  |  |               // Indicate it's a content API route
 | 
					
						
							|  |  |  |               type: 'content-api', | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return strapi.auth.authenticate(ctx, next); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Apollo Server
 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:17:51 +01:00
										 |  |  |         server.getMiddleware({ | 
					
						
							|  |  |  |           path, | 
					
						
							|  |  |  |           cors: serverConfig.cors, | 
					
						
							|  |  |  |           bodyParserConfig: serverConfig.bodyParserConfig, | 
					
						
							|  |  |  |         }), | 
					
						
							| 
									
										
										
										
											2021-09-13 10:48:26 +02:00
										 |  |  |       ], | 
					
						
							|  |  |  |       config: { | 
					
						
							|  |  |  |         auth: false, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Register destroy behavior
 | 
					
						
							| 
									
										
										
										
											2021-08-24 11:01:54 +02:00
										 |  |  |   // We're doing it here instead of exposing a destroy method to the strapi-server.js
 | 
					
						
							|  |  |  |   // file since we need to have access to the ApolloServer instance
 | 
					
						
							|  |  |  |   strapi.plugin('graphql').destroy = async () => { | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |     await server.stop(); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Register the upload middleware powered by graphql-upload in Strapi | 
					
						
							|  |  |  |  * @param {object} strapi | 
					
						
							| 
									
										
										
										
											2021-09-28 11:11:03 +02:00
										 |  |  |  * @param {string} path | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-09-28 11:11:03 +02:00
										 |  |  | const useUploadMiddleware = (strapi, path) => { | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |   const uploadMiddleware = graphqlUploadKoa(); | 
					
						
							| 
									
										
										
										
											2021-08-10 17:28:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 11:31:29 +02:00
										 |  |  |   strapi.server.app.use((ctx, next) => { | 
					
						
							| 
									
										
										
										
											2021-09-28 11:11:03 +02:00
										 |  |  |     if (ctx.path === path) { | 
					
						
							| 
									
										
										
										
											2021-08-10 11:38:52 +02:00
										 |  |  |       return uploadMiddleware(ctx, next); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return next(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }; |