config.module.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import { Module, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
  2. import { ModuleRef } from '@nestjs/core';
  3. import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
  4. import { ConfigurableOperationDef } from '../common/configurable-operation';
  5. import { Injector } from '../common/injector';
  6. import { InjectableStrategy } from '../common/types/injectable-strategy';
  7. import { resetConfig } from './config-helpers';
  8. import { ConfigService } from './config.service';
  9. @Module({
  10. providers: [ConfigService],
  11. exports: [ConfigService],
  12. })
  13. export class ConfigModule implements OnApplicationBootstrap, OnApplicationShutdown {
  14. constructor(
  15. private configService: ConfigService,
  16. private moduleRef: ModuleRef,
  17. ) {}
  18. async onApplicationBootstrap() {
  19. await this.initInjectableStrategies();
  20. await this.initConfigurableOperations();
  21. }
  22. async onApplicationShutdown(signal?: string) {
  23. await this.destroyInjectableStrategies();
  24. await this.destroyConfigurableOperations();
  25. /**
  26. * When the application shuts down, we reset the activeConfig to the default. Usually this is
  27. * redundant, as the app shutdown would normally coincide with the process ending. However, in some
  28. * circumstances, such as when running migrations immediately followed by app bootstrap, the activeConfig
  29. * will persist between these two applications and mutations e.g. to the CustomFields will result in
  30. * hard-to-debug errors. So resetting is a precaution against this scenario.
  31. */
  32. resetConfig();
  33. }
  34. private async initInjectableStrategies() {
  35. const injector = new Injector(this.moduleRef);
  36. for (const strategy of this.getInjectableStrategies()) {
  37. if (typeof strategy.init === 'function') {
  38. await strategy.init(injector);
  39. }
  40. }
  41. }
  42. private async destroyInjectableStrategies() {
  43. for (const strategy of this.getInjectableStrategies()) {
  44. if (typeof strategy.destroy === 'function') {
  45. await strategy.destroy();
  46. }
  47. }
  48. }
  49. private async initConfigurableOperations() {
  50. const injector = new Injector(this.moduleRef);
  51. for (const operation of this.getConfigurableOperations()) {
  52. await operation.init(injector);
  53. }
  54. }
  55. private async destroyConfigurableOperations() {
  56. for (const operation of this.getConfigurableOperations()) {
  57. await operation.destroy();
  58. }
  59. }
  60. private getInjectableStrategies(): InjectableStrategy[] {
  61. const { assetNamingStrategy, assetPreviewStrategy, assetStorageStrategy } =
  62. this.configService.assetOptions;
  63. const {
  64. productVariantPriceCalculationStrategy,
  65. productVariantPriceSelectionStrategy,
  66. productVariantPriceUpdateStrategy,
  67. stockDisplayStrategy,
  68. stockLocationStrategy,
  69. } = this.configService.catalogOptions;
  70. const {
  71. adminAuthenticationStrategy,
  72. shopAuthenticationStrategy,
  73. sessionCacheStrategy,
  74. passwordHashingStrategy,
  75. passwordValidationStrategy,
  76. verificationTokenStrategy,
  77. } = this.configService.authOptions;
  78. const { taxZoneStrategy, taxLineCalculationStrategy } = this.configService.taxOptions;
  79. const { jobQueueStrategy, jobBufferStorageStrategy } = this.configService.jobQueueOptions;
  80. const {
  81. mergeStrategy,
  82. checkoutMergeStrategy,
  83. orderItemPriceCalculationStrategy,
  84. process: orderProcess,
  85. orderCodeStrategy,
  86. orderByCodeAccessStrategy,
  87. stockAllocationStrategy,
  88. activeOrderStrategy,
  89. changedPriceHandlingStrategy,
  90. orderSellerStrategy,
  91. guestCheckoutStrategy,
  92. orderInterceptors,
  93. } = this.configService.orderOptions;
  94. const {
  95. customFulfillmentProcess,
  96. process: fulfillmentProcess,
  97. shippingLineAssignmentStrategy,
  98. } = this.configService.shippingOptions;
  99. const { customPaymentProcess, process: paymentProcess } = this.configService.paymentOptions;
  100. const { entityIdStrategy: entityIdStrategyDeprecated } = this.configService;
  101. const { entityIdStrategy: entityIdStrategyCurrent } = this.configService.entityOptions;
  102. const { healthChecks, errorHandlers } = this.configService.systemOptions;
  103. const { assetImportStrategy } = this.configService.importExportOptions;
  104. const { refundProcess: refundProcess } = this.configService.paymentOptions;
  105. const { cacheStrategy } = this.configService.systemOptions;
  106. const entityIdStrategy = entityIdStrategyCurrent ?? entityIdStrategyDeprecated;
  107. return [
  108. ...adminAuthenticationStrategy,
  109. ...shopAuthenticationStrategy,
  110. sessionCacheStrategy,
  111. passwordHashingStrategy,
  112. passwordValidationStrategy,
  113. verificationTokenStrategy,
  114. assetNamingStrategy,
  115. assetPreviewStrategy,
  116. assetStorageStrategy,
  117. taxZoneStrategy,
  118. taxLineCalculationStrategy,
  119. jobQueueStrategy,
  120. jobBufferStorageStrategy,
  121. mergeStrategy,
  122. checkoutMergeStrategy,
  123. orderCodeStrategy,
  124. orderByCodeAccessStrategy,
  125. entityIdStrategy,
  126. productVariantPriceCalculationStrategy,
  127. productVariantPriceUpdateStrategy,
  128. orderItemPriceCalculationStrategy,
  129. ...orderProcess,
  130. ...customFulfillmentProcess,
  131. ...fulfillmentProcess,
  132. ...customPaymentProcess,
  133. ...paymentProcess,
  134. stockAllocationStrategy,
  135. stockDisplayStrategy,
  136. ...healthChecks,
  137. ...errorHandlers,
  138. assetImportStrategy,
  139. changedPriceHandlingStrategy,
  140. ...(Array.isArray(activeOrderStrategy) ? activeOrderStrategy : [activeOrderStrategy]),
  141. orderSellerStrategy,
  142. shippingLineAssignmentStrategy,
  143. stockLocationStrategy,
  144. productVariantPriceSelectionStrategy,
  145. guestCheckoutStrategy,
  146. ...refundProcess,
  147. cacheStrategy,
  148. ...orderInterceptors,
  149. ];
  150. }
  151. private getConfigurableOperations(): Array<ConfigurableOperationDef<any>> {
  152. const { paymentMethodHandlers, paymentMethodEligibilityCheckers } = this.configService.paymentOptions;
  153. const { collectionFilters } = this.configService.catalogOptions;
  154. const { entityDuplicators } = this.configService.entityOptions;
  155. const { promotionActions, promotionConditions } = this.configService.promotionOptions;
  156. const { shippingCalculators, shippingEligibilityCheckers, fulfillmentHandlers } =
  157. this.configService.shippingOptions;
  158. return [
  159. ...(paymentMethodEligibilityCheckers || []),
  160. ...paymentMethodHandlers,
  161. ...collectionFilters,
  162. ...(promotionActions || []),
  163. ...(promotionConditions || []),
  164. ...(shippingCalculators || []),
  165. ...(shippingEligibilityCheckers || []),
  166. ...(fulfillmentHandlers || []),
  167. ...(entityDuplicators || []),
  168. ];
  169. }
  170. }