graphql-config.service.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { Injectable } from '@nestjs/common';
  2. import { GqlModuleOptions, GqlOptionsFactory, GraphQLTypesLoader } from '@nestjs/graphql';
  3. import { GraphQLUpload } from 'apollo-server-core';
  4. import { extendSchema, printSchema } from 'graphql';
  5. import { GraphQLDateTime } from 'graphql-iso-date';
  6. import * as GraphQLJSON from 'graphql-type-json';
  7. import * as path from 'path';
  8. import { notNullOrUndefined } from '../../../../shared/shared-utils';
  9. import { ConfigService } from '../../config/config.service';
  10. import { I18nService } from '../../i18n/i18n.service';
  11. import { TranslateErrorExtension } from '../middleware/translate-errors-extension';
  12. import { addGraphQLCustomFields } from './graphql-custom-fields';
  13. @Injectable()
  14. export class GraphqlConfigService implements GqlOptionsFactory {
  15. readonly typePaths = path.join(__dirname, '/../../**/*.graphql');
  16. constructor(
  17. private i18nService: I18nService,
  18. private configService: ConfigService,
  19. private typesLoader: GraphQLTypesLoader,
  20. ) {}
  21. createGqlOptions(): GqlModuleOptions {
  22. // Prevent `Type "Node" is missing a "resolveType" resolver.` warnings.
  23. // See https://github.com/apollographql/apollo-server/issues/1075
  24. const dummyResolveType = {
  25. __resolveType() {
  26. return null;
  27. },
  28. };
  29. return {
  30. path: '/' + this.configService.apiPath,
  31. typeDefs: this.createTypeDefs(),
  32. resolvers: {
  33. JSON: GraphQLJSON,
  34. DateTime: GraphQLDateTime,
  35. Node: dummyResolveType,
  36. PaginatedList: dummyResolveType,
  37. Upload: GraphQLUpload,
  38. },
  39. uploads: {
  40. maxFileSize: this.configService.assetOptions.uploadMaxFileSize,
  41. },
  42. playground: true,
  43. debug: true,
  44. context: req => req,
  45. extensions: [() => new TranslateErrorExtension(this.i18nService)],
  46. // This is handled by the Express cors plugin
  47. cors: false,
  48. };
  49. }
  50. /**
  51. * Generates the server's GraphQL schema by combining:
  52. * 1. the default schema as defined in the source .graphql files specified by `typePaths`
  53. * 2. any custom fields defined in the config
  54. * 3. any schema extensions defined by plugins
  55. */
  56. private createTypeDefs(): string {
  57. const customFields = this.configService.customFields;
  58. const typeDefs = this.typesLoader.mergeTypesByPaths(this.typePaths);
  59. let schema = addGraphQLCustomFields(typeDefs, customFields);
  60. const pluginTypes = this.configService.plugins
  61. .map(p => (p.defineGraphQlTypes ? p.defineGraphQlTypes() : undefined))
  62. .filter(notNullOrUndefined);
  63. for (const types of pluginTypes) {
  64. schema = extendSchema(schema, types);
  65. }
  66. return printSchema(schema);
  67. }
  68. }