subscribers.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { EntitySubscriberInterface, EventSubscriber, InsertEvent } from 'typeorm';
  2. import { CALCULATED_PROPERTIES } from '../common/calculated-decorator';
  3. @EventSubscriber()
  4. export class CalculatedPropertySubscriber implements EntitySubscriberInterface {
  5. afterLoad(event: any) {
  6. this.moveCalculatedGettersToInstance(event);
  7. }
  8. afterInsert(event: InsertEvent<any>): Promise<any> | void {
  9. this.moveCalculatedGettersToInstance(event.entity);
  10. }
  11. /**
  12. * For any entity properties decorated with @Calculated(), this subscriber transfers
  13. * the getter from the entity prototype to the entity instance, so that it can be
  14. * correctly enumerated and serialized in the API response.
  15. */
  16. private moveCalculatedGettersToInstance(entity: any) {
  17. if (entity) {
  18. const prototype = Object.getPrototypeOf(entity);
  19. if (prototype.hasOwnProperty(CALCULATED_PROPERTIES)) {
  20. for (const property of prototype[CALCULATED_PROPERTIES]) {
  21. const getterDescriptor = Object.getOwnPropertyDescriptor(prototype, property);
  22. const getFn = getterDescriptor && getterDescriptor.get;
  23. if (getFn && !entity.hasOwnProperty(property)) {
  24. const boundGetFn = getFn.bind(entity);
  25. Object.defineProperties(entity, {
  26. [property]: {
  27. get: () => boundGetFn(),
  28. enumerable: true,
  29. },
  30. });
  31. }
  32. }
  33. }
  34. }
  35. }
  36. }
  37. /**
  38. * A map of the core TypeORM Subscribers.
  39. */
  40. export const coreSubscribersMap = {
  41. CalculatedPropertySubscriber,
  42. };