config.module.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import { Module, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
  2. import { ModuleRef } from '@nestjs/core';
  3. import { ConfigurableOperationDef } from '../common/configurable-operation';
  4. import { Injector } from '../common/injector';
  5. import { InjectableStrategy } from '../common/types/injectable-strategy';
  6. import { resetConfig } from './config-helpers';
  7. import { ConfigService } from './config.service';
  8. @Module({
  9. providers: [ConfigService],
  10. exports: [ConfigService],
  11. })
  12. export class ConfigModule implements OnApplicationBootstrap, OnApplicationShutdown {
  13. constructor(
  14. private configService: ConfigService,
  15. private moduleRef: ModuleRef,
  16. ) {}
  17. async onApplicationBootstrap() {
  18. await this.initInjectableStrategies();
  19. await this.initConfigurableOperations();
  20. }
  21. async onApplicationShutdown(signal?: string) {
  22. await this.destroyInjectableStrategies();
  23. await this.destroyConfigurableOperations();
  24. /**
  25. * When the application shuts down, we reset the activeConfig to the default. Usually this is
  26. * redundant, as the app shutdown would normally coincide with the process ending. However, in some
  27. * circumstances, such as when running migrations immediately followed by app bootstrap, the activeConfig
  28. * will persist between these two applications and mutations e.g. to the CustomFields will result in
  29. * hard-to-debug errors. So resetting is a precaution against this scenario.
  30. */
  31. resetConfig();
  32. }
  33. private async initInjectableStrategies() {
  34. const injector = new Injector(this.moduleRef);
  35. for (const strategy of this.getInjectableStrategies()) {
  36. if (typeof strategy.init === 'function') {
  37. await strategy.init(injector);
  38. }
  39. }
  40. }
  41. private async destroyInjectableStrategies() {
  42. for (const strategy of this.getInjectableStrategies()) {
  43. if (typeof strategy.destroy === 'function') {
  44. await strategy.destroy();
  45. }
  46. }
  47. }
  48. private async initConfigurableOperations() {
  49. const injector = new Injector(this.moduleRef);
  50. for (const operation of this.getConfigurableOperations()) {
  51. await operation.init(injector);
  52. }
  53. }
  54. private async destroyConfigurableOperations() {
  55. for (const operation of this.getConfigurableOperations()) {
  56. await operation.destroy();
  57. }
  58. }
  59. private getInjectableStrategies(): InjectableStrategy[] {
  60. const { assetNamingStrategy, assetPreviewStrategy, assetStorageStrategy } =
  61. this.configService.assetOptions;
  62. const {
  63. productVariantPriceCalculationStrategy,
  64. productVariantPriceSelectionStrategy,
  65. productVariantPriceUpdateStrategy,
  66. stockDisplayStrategy,
  67. stockLocationStrategy,
  68. } = this.configService.catalogOptions;
  69. const {
  70. adminAuthenticationStrategy,
  71. shopAuthenticationStrategy,
  72. sessionCacheStrategy,
  73. passwordHashingStrategy,
  74. passwordValidationStrategy,
  75. verificationTokenStrategy,
  76. } = this.configService.authOptions;
  77. const { taxZoneStrategy, taxLineCalculationStrategy } = this.configService.taxOptions;
  78. const { jobQueueStrategy, jobBufferStorageStrategy } = this.configService.jobQueueOptions;
  79. const { schedulerStrategy } = this.configService.schedulerOptions;
  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, instrumentationStrategy } = 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. ...(instrumentationStrategy ? [instrumentationStrategy] : []),
  149. ...orderInterceptors,
  150. schedulerStrategy,
  151. ];
  152. }
  153. private getConfigurableOperations(): Array<ConfigurableOperationDef<any>> {
  154. const { paymentMethodHandlers, paymentMethodEligibilityCheckers } = this.configService.paymentOptions;
  155. const { collectionFilters } = this.configService.catalogOptions;
  156. const { entityDuplicators } = this.configService.entityOptions;
  157. const { promotionActions, promotionConditions } = this.configService.promotionOptions;
  158. const { shippingCalculators, shippingEligibilityCheckers, fulfillmentHandlers } =
  159. this.configService.shippingOptions;
  160. return [
  161. ...(paymentMethodEligibilityCheckers || []),
  162. ...paymentMethodHandlers,
  163. ...collectionFilters,
  164. ...(promotionActions || []),
  165. ...(promotionConditions || []),
  166. ...(shippingCalculators || []),
  167. ...(shippingEligibilityCheckers || []),
  168. ...(fulfillmentHandlers || []),
  169. ...(entityDuplicators || []),
  170. ];
  171. }
  172. }