id-codec-plugin.ts 2.0 KB

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