id-codec-plugin.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { ApolloServerPlugin, GraphQLRequestListener, GraphQLServerContext } from '@apollo/server';
  2. import { isObject } from '@vendure/common/lib/shared-utils';
  3. import { DocumentNode } from 'graphql';
  4. import { GraphqlValueTransformer } from '../common/graphql-value-transformer';
  5. import { IdCodecService } from '../common/id-codec.service';
  6. /**
  7. * Encodes the ids of outgoing responses according to the configured EntityIdStrategy.
  8. *
  9. * This is done here and not via a Nest Interceptor because it's not possible
  10. * according to https://github.com/nestjs/graphql/issues/320
  11. */
  12. export class IdCodecPlugin implements ApolloServerPlugin {
  13. private graphqlValueTransformer: GraphqlValueTransformer;
  14. constructor(private idCodecService: IdCodecService) {}
  15. async serverWillStart(service: GraphQLServerContext): Promise<void> {
  16. this.graphqlValueTransformer = new GraphqlValueTransformer(service.schema);
  17. }
  18. async requestDidStart(): Promise<GraphQLRequestListener<any>> {
  19. return {
  20. willSendResponse: async requestContext => {
  21. const { document } = requestContext;
  22. if (document) {
  23. const { body } = requestContext.response;
  24. if (body.kind === 'single') {
  25. this.encodeIdFields(document, body.singleResult.data);
  26. }
  27. }
  28. },
  29. };
  30. }
  31. private encodeIdFields(document: DocumentNode, data?: Record<string, unknown> | null) {
  32. if (!data) {
  33. return;
  34. }
  35. const typeTree = this.graphqlValueTransformer.getOutputTypeTree(document);
  36. this.graphqlValueTransformer.transformValues(typeTree, data, (value, type) => {
  37. const isIdType = type && type.name === 'ID';
  38. if (type && type.name === 'JSON' && isObject(value)) {
  39. return this.idCodecService.encode(value, [
  40. 'paymentId',
  41. 'fulfillmentId',
  42. 'orderItemIds',
  43. 'orderLineId',
  44. 'promotionId',
  45. 'refundId',
  46. 'groupId',
  47. 'modificationId',
  48. 'previousCustomerId',
  49. 'newCustomerId',
  50. ]);
  51. }
  52. return isIdType ? this.idCodecService.encode(value) : value;
  53. });
  54. }
  55. }